演示环境
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>
<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.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.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.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.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();
- }
- }
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]
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;