SpringBoot使用JPA

  1. 添加依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    
  2. 添加数据库驱动,以mysql为例

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <scope>runtime</scope>
    </dependency>
    
  3. 数据源和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
    
  4. 创建数据库

    CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET utf8 */;
    
  5. 创建用户并授权

    -- 创建用户并授权
    grant all privileges on test.* to moty@localhost identified by 'Moty123';
    -- 刷新授权表
    flush privileges;
    
  6. 创建实体类

    篇幅有限省略了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() {
        }
    }
    
    
  7. 创建资源库

    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标准定义新接口
    • 接口使用代理实现
  8. 测试

    创建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);
        }
    }
    

  9. 测试运行

    略。


  10. 关于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
posted @ 2018-10-16 13:05  一路向北2557  阅读(77)  评论(0)    收藏  举报