一、为什么使用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层结构
继承自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精讲》。