一、为什么使用Spring Data JPA

上篇文章《SpringBoot讲解一:搭建SSM项目+Thymeleaf+HikariCP》之所以选用Mybatis框架,是因为SSM框架在国内大火了几年,Mybatis几乎成了Java从业者的必备技术。十年前具有煊赫名头,被称之为Java三大框架的SSH,其中的Struts2和Hibernate已经少初学者问津了,而且就算在企业中也是纷纷弃用SSH,选用SSM。

而笔者实际上已经在项目中弃用Mybatis而使用Spring Data JPA了。
之所以这样,
第一,是因为SpringBoot推荐使用Spring Data JPA,大家也都知道只要是SpringBoot推荐使用的技术,SpringBoot都对它们提供了更好的衔接和支持。
第二,Spring Data JPA对Sun的JPA技术做了一定的改进,使用起来更加人性化。其底层实现是Hibernate,Hibernate曾经因为它的繁琐配置和API让人望而却步,但应该没有人质疑它的功能和性能。当初很多人弃用Hibernate这个全ORM框架而选用Mybatis这个半ORM框架就是因为现在我们不想记Hibernate的那些繁琐配置,而退而求其次的使用MyBatis重新写sql语句。而现在只需要使用SpringDataJPA提供的注解和API,就能方便的让底层Hibernate干活,不用书写mysql语句,不用像Mybatis那样捯饬参数、一对多、多对一、多对多关联等等,何乐而不为。

MyBatis这些年其实也有很多插件对它进行简化开发,如mybatis-generator、TKmybatis、mybatis-plugs等等,其实细看来,都是为了避免书让开发者写过多的sql语句,也就是再往另一个Hibernate上发展。但是其对于多表关联关系的处理、性能上跟Hibernate是无法相提并论的。

当然,如果你要继续使用mybatis的话,不会影响接下来的学习,因为本课程起点较高,默认大家已经掌握了SSM框架,dao层不会有复杂操作,用具体哪个持久化框架根据自己喜欢即可。

二、Spring Data JPA简介

Spring Data JPA是Spring提供的一套简化Sun公司的JPA开发的框架,按照约定好的【方法命名规则】写dao层接口,就可以在不写接口实现的情况下,实现对数据库的访问和操作。同时提供了很多除了CRUD之外的功能,如分页、排序、复杂查询等等。

Spring Data JPA 提供了两种Dao层访问数据库的方式:EntityManager和Repository。
其中EntityManager是java.persitince.jpa包下的,用法跟Hibernate的dao层一样,建接口,再建daoImpl实现类。里面用entityManager取代hibernate的session做数据的处理。

另一种是Repository的形式,跟mybatis有点相似,只写接口不写实现类,而且也不用写MyBatis所需要的Sql语句。现在流行使用的正是这一种,以下也是对这样方式的讲解介绍。

三、Spring Data JPA的使用

1.加入依赖:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

注意,如果是基于上一个项目的,需要去除掉Mybatis依赖

2.yml中配置

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/company5?serverTimezone=UTC&characterEncoding=UTF-8
    username: root
    password: 123
  jpa:
    properties:
      hibernate:
        hbm2ddl:
          auto: update
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect
        format_sql: true
        enable_lazy_load_no_trans: true
    show-sql: true
    open-in-view: true

使用Mybatis的话,可以利用一些Mybatis的插件根据表来生成实体类,而Hibernate是一个全ORM框架,让开发者不必关心数据库,甚至不需要打开数据库(当然这是理想化的状态,我们测试的时候还得打开数据库看数据的)了,所以它不能通过表生成实体类,但是却可以通过实体类生成表,以上hbm2ddl的配置就是如此,值为update就是说如果实体类更新了,会将表结构也对应更新。

3.实体类

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(nullable = false, unique = true)//会在mysql中建立唯一索引
    private String name;
    @Column(nullable = false)
    private String sex;
    @Column(nullable = false)
    private int age;
    @JoinColumn(name="d_id")
    @ManyToOne(cascade = CascadeType.MERGE)
    private Department dep;

    public Employee() {
    }

    public Employee(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Department getDep() {
        return dep;
    }
    public void setDep(Department dep) {
        this.dep = dep;
    }
}
@Entity
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column
    private String name;

    //@JoinColumn(name = "d_id")
    @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "dep",fetch=FetchType.LAZY)
    private List<Employee> emps;


    public Department() {
    }

    public Department(String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Employee> getEmps() {
        return emps;
    }

    public void setEmps(List<Employee> emps) {
        this.emps = emps;
    }

}

4.dao层结构

java spring boot 后台界面 spring boot jta_JPA


继承自JpaRepository类后,已经继承了很多默认的方法,如findById,findAll,save,delete等方法,如果实际项目中有这些方法不能解决的问题,则可以自定义方法:

public interface EmployeeRepository extends JpaRepository<Employee, Long> {

    List<Employee> findBySexOrAge(String sex, int age);

    List<Employee> findByName(String name);

    @Query("from Employee as e left join fetch  e.dep where e.id=:id")
    List<Employee> searchHql(Long id);
}

以findBy开头,加上实体类中的属性名,可以使用and和or等连接词进行与或查询,也可以使用与Hibernate的HQL几乎一样的JPQL语句进行查询,也可以使用本地SQL进行查询。

至此,大家便可以通过以上内容,来使用JPA替代Mybatis进行项目开发,如果想要深入学习Spring Data JPA,可以看我下一篇文章《SpringBoot讲解三:Spring Data JPA精讲》。