SpringBoot使用JPA
-
添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> -
添加数据库驱动,以mysql为例
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> -
数据源和JPA配置
spring: datasource: url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8 username: moty password: Moty123 jpa: database: MYSQL show-sql: true #Hibernate ddl auto (validate|create|create-drop|update) hibernate: ddl-auto: update naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy properties: hibernate: dialect: org.hibernate.dialect.MySQL5Dialect -
创建数据库
CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET utf8 */; -
创建用户并授权
-- 创建用户并授权 grant all privileges on test.* to moty@localhost identified by 'Moty123'; -- 刷新授权表 flush privileges; -
创建实体类
篇幅有限省略了getter和setter
package dbdemo.mysql.entity; import com.fasterxml.jackson.annotation.JsonBackReference; import org.springframework.format.annotation.DateTimeFormat; import javax.persistence.*; import java.util.Date; import java.util.List; @Entity @Table(name = "user") public class User implements java.io.Serializable{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createdate; @ManyToOne /**用户与部门多对一*/ @JoinColumn(name = "did") /**关联外键,did表示部门id*/ @JsonBackReference /**防止关系对象的递归访问*/ private Department deparment;/**关联属性*/ @ManyToMany(cascade = {}, fetch = FetchType.EAGER) /**多对多*/ @JoinTable(name = "user_role", /**关联表*/ joinColumns = {@JoinColumn(name = "user_id")},/**关联主键名称*/ inverseJoinColumns = {@JoinColumn(name = "roles_id")})/**关联主键名称*/ private List<Role> roles; public User() { } }
package dbdemo.mysql.entity; import javax.persistence.*; @Entity @Table(name = "role") public class Role implements java.io.Serializable{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; public Role() { } }
package dbdemo.mysql.entity; import javax.persistence.*; @Entity @Table(name = "department") public class Department { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; public Department() { } } -
创建资源库
package dbdemo.mysql.repository; import dbdemo.mysql.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.Date; import java.util.List; @Repository public interface UserRepository extends JpaRepository<User, Long> { User findByNameLike(String name); User readByName(String name); List<User> getByCreatedateLessThan(Date star); }
package dbdemo.mysql.repository; import dbdemo.mysql.entity.Role; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface RoleRepository extends JpaRepository<Role, Long> { }
package dbdemo.mysql.repository; import dbdemo.mysql.entity.Department; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface DepartmentRepository extends JpaRepository<Department, Long> { }
- 继承
JpaRepository接口可实现资源库,对数据库进行crud操作 - 可使用接口自带的增删改查操作,也可基于JPA标准定义新接口
- 接口使用代理实现
- 继承
-
测试
创建JPA配置对象类
package dbdemo.mysql.test; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.Database; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.support.TransactionTemplate; import javax.sql.DataSource; import java.util.Properties; @Configuration /**启用JPA事务管理*/ @EnableTransactionManagement(proxyTargetClass = true) /**指定定义实体的位置,并导入实体*/ @EntityScan(basePackages = "dbdemo.**.entity") /**指定资源库的位置*/ @EnableJpaRepositories(basePackages = "dbdemo.**.repository") public class JpaConfiguration { @Bean PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor(){ return new PersistenceExceptionTranslationPostProcessor(); } @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/test?characterEncoding=utf8"); dataSource.setUsername("moty"); dataSource.setPassword("Moty123"); return dataSource; } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); entityManagerFactoryBean.setDataSource(dataSource()); entityManagerFactoryBean.setPackagesToScan("dbdemo.mysql.entity"); entityManagerFactoryBean.setJpaProperties(buildHibernateProperties()); entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter() {{ setDatabase(Database.MYSQL); }}); return entityManagerFactoryBean; } protected Properties buildHibernateProperties() { Properties hibernateProperties = new Properties(); hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect"); hibernateProperties.setProperty("hibernate.show_sql", "true"); hibernateProperties.setProperty("hibernate.use_sql_comments", "false"); hibernateProperties.setProperty("hibernate.format_sql", "true"); hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "update"); hibernateProperties.setProperty("hibernate.generate_statistics", "false"); hibernateProperties.setProperty("javax.persistence.validation.mode", "none"); //Audit History flags hibernateProperties.setProperty("org.hibernate.envers.store_data_at_delete", "true"); hibernateProperties.setProperty("org.hibernate.envers.global_with_modified_flag", "true"); return hibernateProperties; } @Bean public PlatformTransactionManager transactionManager() { return new JpaTransactionManager(); } @Bean public TransactionTemplate transactionTemplate() { return new TransactionTemplate(transactionManager()); } }
创建测试类
package dbdemo.mysql.test; import dbdemo.mysql.entity.Department; import dbdemo.mysql.entity.Role; import dbdemo.mysql.entity.User; import dbdemo.mysql.repository.DepartmentRepository; import dbdemo.mysql.repository.RoleRepository; import dbdemo.mysql.repository.UserRepository; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.Assert; import java.util.*; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {JpaConfiguration.class}) public class MysqlTest { private static Logger logger = LoggerFactory.getLogger(MysqlTest.class); @Autowired UserRepository userRepository; @Autowired DepartmentRepository departmentRepository; @Autowired RoleRepository roleRepository; @Before public void initData(){ userRepository.deleteAll(); roleRepository.deleteAll(); departmentRepository.deleteAll(); Department department = new Department(); department.setName("开发部"); departmentRepository.save(department); Assert.notNull(department.getId()); Role role = new Role(); role.setName("admin"); roleRepository.save(role); Assert.notNull(role.getId()); User user = new User(); user.setName("user"); user.setCreatedate(new Date()); user.setDeparment(department); List<Role> roles = roleRepository.findAll(); Assert.notNull(roles); user.setRoles(roles); userRepository.save(user); Assert.notNull(user.getId()); } @Test public void findPage(){ Pageable pageable = new PageRequest(0, 10, new Sort(Sort.Direction.ASC, "id")); Page<User> page = userRepository.findAll(pageable); Assert.notNull(page); for(User user : page.getContent()) { logger.info("====user==== user name:{}, department name:{}, role name:{}", user.getName(), user.getDeparment().getName(), user.getRoles().get(0).getName()); } } //@Test public void test(){ User user1 = userRepository.findByNameLike("u%"); Assert.notNull(user1); User user2 = userRepository.readByName("user"); Assert.notNull(user2); List<User> users = userRepository.getByCreatedateLessThan(new Date()); Assert.notNull(users); } }
-
测试运行
略。
-
关于JPA
- Java Persistence API(Java 持久层 API):用于对象持久化的 API
- JPA 是一种 ORM 规范,hibernate是JPA的一种实现。
- JPA能自动代理按照规范命名的方法
- 前缀
findBy,readBy,getBy拼接驼峰式的属性名 - 可拼接关键字:
And,Or,Between,LessThan,GreaterThan,IsNull,IsNotNull,NotNull,Like,NotLike,OrderBy,In,NotIn,Not等
- 前缀
浙公网安备 33010602011771号