一、JPA简介

JPA (Java Persistence API) 是 Sun 官方提出的 Java 持久化规范。它为 Java 开发人员提供了一种对象/关联映射工具来管理 Java 应用中的关系数据。它的出现主要是为了简化现有的持久化开发工作和整合 ORM 技术,结束现在 Hibernate,TopLink,JDO 等 ORM 框架各自为营的局面。

JPA 是在充分吸收了现有 Hibernate,TopLink,JDO 等 ORM 框架的基础上发展而来的,具有易于使用,伸缩性强等优点。注意: JPA 是一套规范,不是一套产品,像Hibernate,TopLink,JDO 这些是一套产品,如果说这些产品实现了这个 JPA 规范,那么我们就可以叫他们为 JPA 的实现产品。

Spring Boot JPA 是 Spring 基于 ORM 框架、 JPA 规范的基础上封装的一套 JPA 应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率!

二、项目实践

  1. 创建一个spring boot项目,项目结构如下:
  2. 导入相关maven依赖,这里主要是JPA和mysql的相关依赖:
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
  1. 编写application.yml配置文件:
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/bg-learnsp?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.zaxxer.hikari.HikariDataSource
    # 数据源简单配置
    hikari:
      auto-commit: true
      pool-name: testLearnJpa
      minimum-idle: 2
      maximum-pool-size: 5
      idle-timeout: 60000
  # JPA相关配置
  jpa:
    show-sql: true # 是否显示执行SQL
    database: mysql # 数据库类型
    generate-ddl: true # 生成dll语句
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect # 设置hibernate方言
    hibernate:
      ddl-auto: update # 每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)

上面关于JPA的相关配置都比较容易理解,重点解释一下 spring.jpa.hibernate.ddl-auto这个属性,它的取值有5个,如下:

  • create :每次加载hibernate时都会删除上一次的生成的表,然后根据你的数据库实体类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
  • create-drop :每次加载hibernate时根据数据库实体类生成表,但是sessionFactory一关闭,表就自动删除。
  • update :最常用的属性,第一次加载hibernate时根据数据库实体类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据数据库实体类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会。
  • validate :每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
  • none :不做任何操作。

具体解释可以参考Spring Data JPA访问MySQL数据库,想要了解更多配置信息,可以访问Spring Data JPA相关配置

  1. 创建数据库映射的实体类:
/**
 * @ClassName: UserEntity
 * @Description:
 * @author: jinghuaixin
 * @date: 2020/8/25 12:13
 */
@Data
@Entity //告诉Hibernate使用这个类创建一个表
@Table(name = "user") // 指定数据库表名
public class UserEntity {
    @Id // 指定主键
    @GeneratedValue(strategy = GenerationType.AUTO) //指定主键自增
    private Long id;

    @Column(nullable = false, name = "name")
    private String name;

    private Integer age;

}

创建实体类对象时,需要使用注解对应到数据库中的表上,上面的注解已经较为详细的注释了含义,也可以参考Spring Data JPA访问MySQL数据库

  1. 创建DAO层,UserRepository:
public interface UserRepository extends JpaRepository<UserEntity, Long> {

    /**
     * 通过id查询用户信息
     *
     * @param id
     * @return
     */
    UserEntity getByIdIs(Long id);

}

JpaRepository是JPA提供的一个接口,我们创建的UserRepository继承这个接口即可,接口有两个泛型,第一个是数据库表对应的实体类类型,第二个是主键的类型。

简单看一下JpaRepository接口相关的层次结构:

POSTGRESQL 的 JSON 对应 java哪个类型 jpa mysql json_MySQL

  • 打开CrudRepository接口:
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
    <S extends T> S save(S var1);

    <S extends T> Iterable<S> saveAll(Iterable<S> var1);

    Optional<T> findById(ID var1);

    boolean existsById(ID var1);

    Iterable<T> findAll();

    Iterable<T> findAllById(Iterable<ID> var1);

    long count();

    void deleteById(ID var1);

    void delete(T var1);

    void deleteAll(Iterable<? extends T> var1);

    void deleteAll();
}
  • 打开JpaRepository接口:
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
    List<T> findAll();

    List<T> findAll(Sort var1);

    List<T> findAllById(Iterable<ID> var1);

    <S extends T> List<S> saveAll(Iterable<S> var1);

    void flush();

    <S extends T> S saveAndFlush(S var1);

    void deleteInBatch(Iterable<T> var1);

    void deleteAllInBatch();

    T getOne(ID var1);

    <S extends T> List<S> findAll(Example<S> var1);

    <S extends T> List<S> findAll(Example<S> var1, Sort var2);
}

可以看到CrudRepository接口和JpaRepository接口中已经定义了大量方法,UserRepository 继承了JpaRepository接口,在业务开发中,可以直接调用这些方法,不需要自己再次实现了。
此外,Spring Boot JPA 帮我们定义了很多自定义的简单查询,并且可以根据方法名来自动生成 SQL ,主要的语法是 findXXBy , readAXXBy , queryXXBy , countXXBy , getXXBy 后面跟属性名称。具体可以参考Spring Data JPA使用Repository。

  1. 编写测试用例:
@SpringBootTest
class SpLearnJpaApplicationTests {

    @Autowired
    private UserRepository userRepository;

    @Test
    void testUserRepository() {
        UserEntity userEntity = new UserEntity();
        userEntity.setName("hell,JPA");
        userEntity.setAge(20);
        //保存用户信息
        userRepository.save(userEntity);
        //查询用户信息
        UserEntity user = userRepository.getByIdIs(userEntity.getId());
        System.out.println(user);
    }

}

截取部分运行结果:

Hibernate: create table hibernate_sequence (next_val bigint) engine=InnoDB
Hibernate: insert into hibernate_sequence values ( 1 )
Hibernate: create table user (id bigint not null, age integer, name varchar(255) not null, primary key (id)) engine=InnoDB
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: insert into user (age, name, id) values (?, ?, ?)
Hibernate: select userentity0_.id as id1_0_, userentity0_.age as age2_0_, userentity0_.name as name3_0_ from user userentity0_ where userentity0_.id=?
UserEntity(id=1, name=hell,JPA, age=20)

到这里,简单使用JPA访问MySQL数据库的小案例就搭建好了,如果想要更多了解Spring Data JPA,可以访问Spring Data JPA官网和查看Spring Data JPA官方文档