Spring Data JPA使用複合主鍵
演示環境
MySQL 5.7
JDK1.8
spring-data-jpa 1.10.4.RELEASE
hibernate 5.1.2.Final
這裡演示一個餘額寶的例子,一個使用者一天一條記錄,表示一個使用者一天的收益情況。其中,使用者ID,日期是複合主鍵
專案總體結構如下:
下面依次貼出原始碼
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.pp.jpa</groupId> <artifactId>springdata-jpa</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>springdata-jpa</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.40</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>1.10.4.RELEASE</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.1.2.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>5.1.2.Final</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </project>
下面依次是Java原始碼
package com.pp.jpa.config; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; @Configuration public class JPAConfiguration { @Bean public DataSource createDataSource(){ MysqlDataSource ds = new MysqlDataSource(); ds.setURL("jdbc:mysql://127.0.0.1:3306/jpa"); ds.setUser("root"); ds.setPassword("admin123"); return ds; } @Bean(name="entityManagerFactory") public EntityManagerFactory createEntityManagerFactory(DataSource dataSource){ LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean(); entityManagerFactory.setDataSource(dataSource); HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter(); jpaVendorAdapter.setGenerateDdl(true); jpaVendorAdapter.setShowSql(true); entityManagerFactory.setPackagesToScan("com.pp.jpa.entity"); entityManagerFactory.setJpaVendorAdapter(jpaVendorAdapter); entityManagerFactory.afterPropertiesSet(); return entityManagerFactory.getObject(); } @Bean(name="transactionManager") public PlatformTransactionManager createPlatformTransactionManager(EntityManagerFactory entityManagerFactory){ JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(entityManagerFactory); return transactionManager; } }
package com.pp.jpa.entity; import java.io.Serializable; import javax.persistence.Embeddable; /** * 主鍵 * 代表複合主鍵的實體bean需要實現Serializable介面 */ @Embeddable public class UserFundPrimarykey implements Serializable { private static final long serialVersionUID = 1L; //使用者ID private Integer userId; /** * 日期,格式yyyy-MM-dd */ private String date; public UserFundPrimarykey() {} public UserFundPrimarykey(Integer userId, String date) { this.userId = userId; this.date = date; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } @Override public String toString() { return "UserFundPrimarykey [userId=" + userId + ", date=" + date + "]"; } }
package com.pp.jpa.entity;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* 模擬一個餘額寶的功能
* 一條記錄代表一個使用者一天的收益資訊(本金,利率,利息)
*/
@Entity
@Table(name = "user_funds")
public class UserFund {
/**
* 主鍵
* 複合主鍵不能用@Id,需要用@EmbeddedId。插入資料的時候必須手工賦值
*/
@EmbeddedId
private UserFundPrimarykey userFundPK;
//本金
@Column(precision=18, scale=5)
private BigDecimal principal;
//利率(5%傳0.05)
@Column(precision=18, scale=5)
private BigDecimal rate;
/**
* 當天收益(日利息=本金*利率/365)
* 保留2位小數
*/
@Column(precision=18, scale=2)
private BigDecimal interest;
public UserFundPrimarykey getUserFundPK() {
return userFundPK;
}
public void setUserFundPK(UserFundPrimarykey userFundPK) {
this.userFundPK = userFundPK;
}
public BigDecimal getPrincipal() {
return principal;
}
public void setPrincipal(BigDecimal principal) {
this.principal = principal;
}
public BigDecimal getRate() {
return rate;
}
public void setRate(BigDecimal rate) {
this.rate = rate;
}
public BigDecimal getInterest() {
return interest;
}
public void setInterest(BigDecimal interest) {
this.interest = interest;
}
@Override
public String toString() {
return "UserFund [userFundPK=" + userFundPK + ", principal=" + principal + ", rate=" + rate + ", interest="
+ interest + "]";
}
}
package com.pp.repository;
import org.springframework.data.repository.CrudRepository;
import com.pp.jpa.entity.UserFund;
import com.pp.jpa.entity.UserFundPrimarykey;
public interface UserFundRepository extends CrudRepository<UserFund, UserFundPrimarykey> {
}
啟動類
package com.pp.jpa;
import java.math.BigDecimal;
import java.math.RoundingMode;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.pp.jpa.entity.UserFund;
import com.pp.jpa.entity.UserFundPrimarykey;
import com.pp.repository.UserFundRepository;
@ComponentScan
@EnableJpaRepositories(value="com.pp")
@EnableTransactionManagement
public class App {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(App.class);
UserFund uf1 = new UserFund();
//必須手動設定主鍵
uf1.setUserFundPK(new UserFundPrimarykey(1, "2017-07-01"));
uf1.setRate(new BigDecimal("0.041"));
uf1.setPrincipal(new BigDecimal("10000"));
//截斷,只保留兩位小數
uf1.setInterest(uf1.getRate().multiply(uf1.getPrincipal()).divide(new BigDecimal("365"), 2, RoundingMode.DOWN));
UserFund uf2 = new UserFund();
//必須手動設定主鍵
uf2.setUserFundPK(new UserFundPrimarykey(2, "2017-07-01"));
uf2.setRate(new BigDecimal("0.041"));
uf2.setPrincipal(new BigDecimal("20000"));
//截斷,只保留兩位小數
uf2.setInterest(uf2.getRate().multiply(uf2.getPrincipal()).divide(new BigDecimal("365"), 2, RoundingMode.DOWN));
UserFundRepository ur = context.getBean(UserFundRepository.class);
ur.save(uf1);
ur.save(uf2);
ur.findAll().forEach(System.out::println);
//查詢使用者ID=2,在2017-07-01這一天的收益
System.out.println(ur.findOne(new UserFundPrimarykey(2, "2017-07-01")));
context.close();
}
}
一些注意事項和做法已經在備註中有寫,大家模仿著寫就OK了
直接執行main方法,控制檯輸出如下資訊
Hibernate: select userfund0_.date as date1_0_0_, userfund0_.userId as userId2_0_0_, userfund0_.interest as interest3_0_0_, userfund0_.principal as principa4_0_0_, userfund0_.rate as rate5_0_0_ from user_funds userfund0_ where userfund0_.date=? and userfund0_.userId=?
Hibernate: insert into user_funds (interest, principal, rate, date, userId) values (?, ?, ?, ?, ?)
Hibernate: select userfund0_.date as date1_0_0_, userfund0_.userId as userId2_0_0_, userfund0_.interest as interest3_0_0_, userfund0_.principal as principa4_0_0_, userfund0_.rate as rate5_0_0_ from user_funds userfund0_ where userfund0_.date=? and userfund0_.userId=?
Hibernate: insert into user_funds (interest, principal, rate, date, userId) values (?, ?, ?, ?, ?)
Hibernate: select userfund0_.date as date1_0_, userfund0_.userId as userId2_0_, userfund0_.interest as interest3_0_, userfund0_.principal as principa4_0_, userfund0_.rate as rate5_0_ from user_funds userfund0_
UserFund [userFundPK=UserFundPrimarykey [userId=1, date=2017-07-01], principal=10000.00000, rate=0.04100, interest=1.12]
UserFund [userFundPK=UserFundPrimarykey [userId=2, date=2017-07-01], principal=20000.00000, rate=0.04100, interest=2.24]
Hibernate: select userfund0_.date as date1_0_0_, userfund0_.userId as userId2_0_0_, userfund0_.interest as interest3_0_0_, userfund0_.principal as principa4_0_0_, userfund0_.rate as rate5_0_0_ from user_funds userfund0_ where userfund0_.date=? and userfund0_.userId=?
UserFund [userFundPK=UserFundPrimarykey [userId=2, date=2017-07-01], principal=20000.00000, rate=0.04100, interest=2.24]
查詢資料庫
select ** from user_funds;
最後說一句,餘額寶的利息好低啊,一萬塊錢存一天,只有1塊錢左右
相關推薦
Spring Data Jpa 複合主鍵
這次大創有個需求,在資料庫建表時發現,user表與project表的關係表 user_project的主鍵為複合主鍵: CREATE TABLE user_project( user_id INT(20), project_id
Spring JPA 複合主鍵
Spring JPA 複合主鍵配置 1. 建立複合主鍵類,類上新增@Embeddable註解,注意要實現 Serializabl
springboot jpa 複合主鍵
https://blog.csdn.net/wyc_cs/article/details/9031991 建立一個複合主鍵類 public class LevelPostMultiKeysClass implements Serializable{ private Integer
JPA複合主鍵使用
資料庫表 create table RENT_CERT_VENDOR_TYPE ( CERT_TYPE_ID NUMBER not null, VENDOR_ID NUMBER not null, CERT_TYPE_VENDOR
JPA複合主鍵另一種實現--聯合約束
前言 關於複合主鍵一般是三種方式,但必須建立複合主鍵類,然後通過註解的方式完成,這三種方式網上很容易找到,這裡主要記錄自己使用時的一些坑和專案中的特殊需求。 結合JPA使用時,關於Repository類中第二個引數不再是Long(主鍵id型別),而是複合主
springboot jpa 複合主鍵 聯合主鍵
開發十年,就只剩下這套架構體系了! >>>
Spring Data JPA使用複合主鍵
演示環境 MySQL 5.7 JDK1.8 spring-data-jpa 1.10.4.RELEASE hibernate 5.1.2.Final 這裡演示一個餘額寶的例子,一個使用者一天一條記錄,表示一個使用者一天的收益情況。其中,使用者ID,日期是複合主鍵 專案總體結
spring data jpa save 返回 主鍵問題
除錯時發現,如果呼叫 Repository 的 save 方法時,對應的主鍵,還是為空。以為是什麼bug。 後面查閱資料發現。其實是在返回值中,而不是傳入值中。 檢視SimpleJpaRepository原始碼,除錯發現,如果是走persist(新增,判斷是否新,是看是不是nu
Spring cloud Jpa 的三種複合主鍵查詢(實體類操作,sql語句裡操作)
今天剛好有個sql查詢,查出來的時候發現數據重複(可能說是覆蓋了更為準確些)了,條數是對的,再去debug一遍,發現是jpa自定義的實體類那裡出了問題,主鍵id只有一個,因為查出來的資料是複合主鍵的,所以只找到了實體類中定義的一個ID,可能就導致了資料覆蓋,但是條數是正確
Spring Data Rest遇到複合主鍵
如果專案持久層使用Spring Data JPA且某些資料表中含有複合主鍵(聯合主鍵),使用Spring Data Rest生成的介面如何訪問這些資料表中的某個主鍵對應的資料呢? 假設資料庫有2個有複合主鍵的資料表film_actor和film_categor
spring-data-jpa使用聯合主鍵後出現operand should contain 1 column(s)
最近做專案遇到個比較坑的地方,今天有空記錄下來,希望可以為遇到同樣情況的朋友提供一個方法。 因為業務邏輯上的問題,專案寫到前幾天突然發現要重新設計資料庫某個表的主鍵。(在團隊同學的建議下),採用了之前一直沒機會接觸過的聯合主鍵。 專案用的是mySql,資料表修改成
Spring Data JPA 實例查詢
customer 數據庫表 查詢方式 記錄 如何 三、認識“實例查詢” 1、概念定義: 上面例子中,是這樣創建“實例”的:Example<Customer> ex = Example.of(customer, matcher);我們看到,Example對象,由custom
Spring Data Jpa緩存介紹
級別 instance osc vid group 進程 config 詳細配置 oca 一級緩存: 會話session、事務級別的,事務退出,緩存就失效了。以id為標識 實體管理器-數據源 操作數據拷貝而非數據源。 二級緩存: 線程級或集群級,以id為標識放到緩存(針
SpringBoot中使用Spring Data Jpa 實現簡單的動態查詢的兩種方法
ppr eat value table 得到 blog .net ride integer 首先謝謝大佬的簡書文章:http://www.jianshu.com/p/45ad65690e33# 這篇文章中講的是spring中使用spring data jpa,使用了xml配
spring boot + spring data jpa
分享 users pac frame 配置文件 .sql lda hash chan Spring Data Repository的核心接口是Repository(好像也沒什麽好驚訝的)。這個接口需要領域類(Domain Class)跟領域類的ID類型作為參數。這個接
Spring Boot入門第二天:一個基於Spring Boot的Web應用,使用了Spring Data JPA和Freemarker。
per pan let mysq 應用 posit ble host thead 今天打算從數據庫中取數據,並展示到視圖中。不多說,先上圖: 第一步:添加依賴。打開pom.xml文件,添加必要的依賴,完整代碼如下: <?xml version="1.0" enco
spring data jpa 關聯設計
join umt table cto ring pre any collect rate MAP關聯實體 // @ElementCollection @OneToMany(cascade = {CascadeType.ALL})// @JoinColumn
Spring Data JPA 參考指南 中文版
參考 指南 get www. book git pri 地址 blank 附下載地址:https://www.gitbook.com/book/ityouknow/spring-data-jpa-reference-documentation/detailsSpring D
spring data jpa自定義baseRepository
ram clas over 找到 ict app ray 註冊 基於 在一些特殊時候,我們會設計到對Spring Data JPA中的方法進行重新實現,這將會面臨一個問題,如果我們新創建一個實現類。如果這個實現類實現了JpaRepository接口,這樣我們不得不實現該接口
Spring Data JPA動態查詢(多條件and)
ica cat 滿足 from pos true ans let tid entity: @Entity @Table(name = "data_illustration") public class Test { @Id @Gen