当前位置 博文首页 > RtxTitanV的博客:SpringBoot2.x 集成 SpringDataJpa

    RtxTitanV的博客:SpringBoot2.x 集成 SpringDataJpa

    作者:[db:作者] 时间:2021-07-07 12:39

    SpringDataJpa简介:Spring Data JPA是Spring Data家族的一员,可以轻松实现基于JPA的存储库。该模块处理对基于JPA的数据访问层的增强支持。这使得构建使用数据访问技术的Spring应用程序变得更加容易。
    在相当长的一段时间内,实现应用程序的数据访问层一直很麻烦。必须编写太多样板代码来执行简单查询以及执行分页和审计。Spring Data JPA旨在通过减少实际需要的工作量来显著改善数据访问层的实现。作为开发人员,你编写repository接口,包括自定义查询器方法,Spring将自动提供实现。

    下面通过SpringBoot2.x集成SpringDataJpa并进行基本的使用测试,其中SpringBoot使用的2.2.2.RELEASE版本。

    一、引入依赖

    <!-- Spring Data 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>
    </dependency>
    <!-- lombok插件 可选(推荐) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.8</version>
    </dependency>
    <!-- 单元测试依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    

    二、编写配置文件

    resources目录下新建application.yml配置文件,配置内容如下:

    spring:
      # mysql数据库连接信息
      datasource:
        # 高版本mysql驱动
        driver-class-name: com.mysql.cj.jdbc.Driver
        # 使用com.mysql.cj.jdbc.Driver驱动需要带上时区serverTimezone
        url: jdbc:mysql://127.0.0.1:3306/test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
        username: root
        password: root
      # jpa相关配置
      jpa:
      	# 数据库使用mysql
        database: mysql
        # 控制台是否显示sql语句,true:显示 false:不显示
        show-sql: true
        # 是否根据实体类(@Entity注解的类)自动建表,true:是 false:否,默认为false
        generate-ddl: true
        hibernate:
          # 自动创建或更新或验证数据库表结构,省略不会自动建表
          # create:每次加载Hibernate时都会删除上一次生成的表,然后根据Entity类再重新来生成新表,即使两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因
          # create-drop:每次加载Hibernate时根据Entity类生成表,但是sessionFactory一关闭,表就自动删除
          # update:最常用的属性,第一次加载Hibernate时根据Entity类会自动建立起表的结构(前提是先建立好数据库),以后加载Hibernate时根据Entity类自动更新表结构,
          # 即使表结构改变了,但表中的行仍然存在,不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会
          # validate:每次加载Hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值
          ddl-auto: update
        # 设置数据库存储引擎为InnoDB
        database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    

    三、创建实体类并配置映射关系

    package com.rtxtitanv.model;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import javax.persistence.*;
    
    /**
     * @author rtxtitanv
     * @version 1.0.0
     * @name com.rtxtitanv.model.User
     * @description 用户实体类
     * @date 2019/12/31 18:49
     */
    @Accessors(chain = true) // lombok注解,支持链式编程
    @AllArgsConstructor // lombok注解,自动生成全参构造器
    @NoArgsConstructor // lombok注解,自动生成无参构造器
    @Data // lombok注解,自动生成get、set、toString等方法
    @Entity // 声明实体类
    @Table(name = "user") // 建立实体类与表的映射关系
    public class User {
        @Id // 声明该实例域为主键
        @GeneratedValue(strategy = GenerationType.IDENTITY) // 主键生成策略,IDENTITY:由数据库自行管理
        // 建立实例域id与表中字段id的映射关系
        @Column(name = "id")
        private Long id;
        // 建立实例域uid和表中字段uid的映射关系,length:指定此字段的长度,只对字符串有效,不写默认为255
        // unique:是否添加唯一约束,不写时默认为false,nullable:表示此字段是否允许为null
        @Column(name = "uid", length = 64, unique = true, nullable = false)
        private String uid;
        // 建立实例域userName和表中字段user_name的映射关系
        @Column(name = "user_name", length = 16, unique = true, nullable = false)
        private String userName;
        // 建立实例域passWord和表中字段pass_word的映射关系
        @Column(name = "pass_word", length = 16, nullable = false)
        private String passWord;
        // 建立实例域nickName和表中字段nick_name的映射关系
        @Column(name = "nick_name", length = 16)
        private String nickName;
        // 建立实例域age和表中字段age的映射关系
        @Column(name = "age")
        private Integer age;
        // 建立实例域email和表中字段email的映射关系
        @Column(name = "email", unique = true, nullable = false)
        private String email;
        // 建立实例域tel和表中字段tel的映射关系
        @Column(name = "tel", unique = true, nullable = false)
        private String tel;
        // 建立实例域regTime和表中字段reg_time的映射关系
        @Column(name = "reg_time", nullable = false)
        private String regTime;
        // 该实例域并非一个到数据库表的字段的映射,ORM框架将忽略该域
        @Transient
        private String addr;
    }
    

    注意:
    1.如果类中的实例域使用枚举类型时,我们想要数据库中存储的是枚举对应的String类型值,而不是枚举的索引值时,需要在实例域上面添加注解@Enumerated(EnumType.STRING),例如:

    @Enumerated(EnumType.STRING) 
    @Column(name = "user_type")
    private UserType type;
    

    2.如果实体类不在启动类所在包及其子包下,则需要在主启动类上加上以下注解:
    @EntityScan(basePackages = {"包含实体类的包路径"})
    如果有多个包路径,只需要在主启动类上加上以下注解:
    @EntityScan(basePackages = {"包含实体类的包路径1", "包含实体类的包路径2", ..., "包含实体类的包路径n"})

    四、创建Repository接口

    package com.rtxtitanv.repository;
    
    import com.rtxtitanv.model.User;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
    
    /**
     * @author rtxtitanv
     * @version 1.0.0
     * @name com.rtxtitanv.repository.UserRepository
     * @description UserRepository接口用于操作用户表,JpaRepository<实体类类型, 主键类型>:用于完成基本CRUD,分页,排序操作
     * JpaSpecificationExecutor<实体类类型>:用于复杂查询
     * @date 2019/12/31 19:31
     */
    public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
    }
    

    五、SpringDataJpa的使用测试

    首先启动主启动类,会在数据库中建立一张user表,表中暂无数据,建表信息如下:

    2020-01-01 13:00:24.612  INFO 16552 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
    Hibernate: create table user (id bigint not null auto_increment, age integer, email varchar(255) not null, nick_name varchar(16), pass_word varchar(16) not null, reg_time varchar(255) not null, tel varchar(255) not null, uid varchar(64) not null, user_name varchar(16) not null, primary key (id)) engine=InnoDB
    Hibernate: alter table user drop index UK_ob8kqyqqgmefl0aco34akdtpe
    Hibernate: alter table user add constraint UK_ob8kqyqqgmefl0aco34akdtpe unique (email)
    Hibernate: alter table user drop index UK_nbfia2ok6c7at4i0er6uyskkx
    Hibernate: alter table user add constraint UK_nbfia2ok6c7at4i0er6uyskkx unique (tel)
    Hibernate: alter table user drop index UK_a7hlm8sj8kmijx6ucp7wfyt31
    Hibernate: alter table user add constraint UK_a7hlm8sj8kmijx6ucp7wfyt31 unique (uid)
    Hibernate: alter table user drop index UK_lqjrcobrh9jc8wpcar64q1bfh
    Hibernate: alter table user add constraint UK_lqjrcobrh9jc8wpcar64q1bfh unique (user_name)
    

    在这里插入图片描述
    SpringDataJpa单元测试类

    package com.rtxtitanv;
    
    import com.rtxtitanv.repository.UserRepository;
    import org.junit.runner.RunWith;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    /**
     * @author rtxtitanv
     * @version 1.0.0
     * @name com.rtxtitanv.JpaTest
     * @description SpringDataJpa单元测试类
     * @date 2019/12/31 20:05
     */
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = JpaApplication.class)
    public class JpaTest {
    
        @Autowired
        private UserRepository userRepository;
        private static Logger logger = LoggerFactory.getLogger(JpaTest.class);
    }
    

    1.基本的增删改查

    使用JpaRepository接口自带的方法进行基本的增删改查。

    (1)新增测试

    ①保存单条记录

    	/**
         * 保存5条测试数据,一次插入一条数据
         * 使用方法 <S extends T> S save(S var1)
         * 实体中主键不存在时保存记录
         */
        @Test
        public void saveTest() {
            Date date = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String formattedDate = dateFormat.format(date);
            logger.info("保存5条测试数据开始");
            userRepository.save(new User(null, "296ebeb46acd49aca54f0d5a5a1257c3", "qwer123", "123456", "aaa", 24,
                    "qwer123@ss.com", "13915176512", formattedDate, "beijing"));
            userRepository.save(new User(null, "e6c133e338bb4b7c857be76104986acb", "asd6666", "qw23ss"