Java 持久层框架访问数据库的方式大致分为两种。

  1.  以SQL 核心,封装一定程度的 JDBC 操作,比如: MyBatis。
  2. 以 Java 实体类为核心,将实体类的和数据库表之间建立映射关系,也就是我们说的ORM框架,如:Hibernate、Spring Data JPA

JPA是啥?

JPA全称为Java Persistence API(Java持久层API),它是Sun公司在JavaEE 5中提出的Java持久化规范。它为Java开发人员提供了一种对象/关联映射工具,来管理Java应用中的关系数据,JPA吸取了目前Java持久化技术的优点,旨在规范、简化Java对象的持久化工作。很多ORM框架都是实现了JPA的规范,如:Hibernate、EclipseLink。

需要注意的是JPA统一了Java应用程序访问ORM框架的规范(JPA是一种规范)

 

JPA为我们提供了以下规范:

1. ORM映射元数据:JPA支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中

2. JPA 的API:用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发人员不用再写SQL了

3. JPQL查询语言:通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。

 

Hibernate是啥

Hibernate是Java中的对象关系映射解决方案。对象关系映射或ORM框架是将应用程序数据模型对象映射到关系数据库表的技术。Hibernate 不仅关注于从 Java 类到数据库表的映射,也有 Java 数据类型到 SQL 数据类型的映射。

 

Spring Data是啥

Spring Data是Spring 社区的一个子项目,主要用于简化数据(关系型&非关系型)访问,其主要目标是使得数据库的访问变得方便快捷。

它提供很多模板操作

– Spring Data Elasticsearch

– Spring Data MongoDB

– Spring Data Redis

– Spring Data Solr

强大的 Repository 和定制的数据储存对象的抽象映射

对数据访问对象的支持

 

Spring Data JPA又是啥

Spring Data JPA是在实现了JPA规范的基础上封装的一套 JPA 应用框架,虽然ORM框架都实现了JPA规范,但是在不同的ORM框架之间切换仍然需要编写不同的代码,而使用Spring Data JPA能够方便大家在不同的ORM框架之间进行切换而不需要更改代码。Spring Data JPA旨在通过将统一ORM框架的访问持久层的操作,来提高开发人的效率

 

springboot jpa和hibernate的区别_数据库

 

Spring Data JPA给我们提供的主要的类和接口

Repository 接口:

Repository

CrudRepository

JpaRepository

Repository 实现类:

SimpleJpaRepository

QueryDslJpaRepository

 

Spring Data JPA和Hibernate的关系

Hibernate其实是JPA的一种实现,而Spring Data JPA是一个JPA数据访问抽象。也就是说Spring Data JPA不是一个实现或JPA提供的程序,它只是一个抽象层,主要用于减少为各种持久层存储实现数据访问层所需的样板代码量。但是它还是需要JPA提供实现程序,其实Spring Data JPA底层就是使用的 Hibernate实现。

小结:

Hibernate是JPA的一种实现,是一个框架

JPA是一种规范(Java应用访问ORM的规范)

Spring Data JPA是一种JPA的抽象层,底层依赖Hibernate

 

 

spring-data-jpa能够帮助你完成业务逻辑代码的处理

此时不需要UserDaoImpl这个类,只需要在UserRepository接口中定义一个方法

User findByNameAndPassword(String name, String password);

然后在service中调用这个方法即可,所有的逻辑只需要这么一行代码,一个没有实现的接口方法。通过debug信息,我们看到输出的sql语句是

select * from user where name = ? and password = ?

跟上面的传统方式一模一样的结果。原理是:spring-data-jpa会根据方法的名字来自动生成sql语句,我们只需要按照方法定义的规则即可,上面的方法findByNameAndPassword,spring-data-jpa规定,方法都以findBy开头,sql的where部分就是NameAndPassword,被spring-data-jpa翻译之后就编程了下面这种形态:

where name = ? and password = ?

在举个例,如果是其他的操作符呢,比如like,前端模糊查询很多都是以like的方式来查询。比如根据名字查询用户,sql就是

select * from user where name like = ?

这里spring-data-jpa规定,在属性后面接关键字,比如根据名字查询用户就成了

User findByNameLike(String name);

被翻译之后的sql就是

select * from user where name like = ?

 

定义规则:

springboot jpa和hibernate的区别_数据库_02

 

 

总结一下使用动态查询:原生api需要4步,而使用spring-data-jpa只需要一步,那就是重写匿名内部类的toPredicate方法

eg:

1     @Override
 2     public Page<Student> search(final Student student, PageInfo page) {
 4         return studentRepository.findAll(new Specification<Student>() {
 5             @Override
 6             public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
 7                 
 8                 Predicate stuNameLike = null;
 9                 if(null != student && !StringUtils.isEmpty(student.getName())) {
10                     stuNameLike = cb.like(root.<String> get("name"), "%" + student.getName() + "%");
11                 }
12                 
13                 Predicate clazzNameLike = null;
14                 if(null != student && null != student.getClazz() && !StringUtils.isEmpty(student.getClazz().getName())) {
15                     clazzNameLike = cb.like(root.<String> get("clazz").<String> get("name"), "%" + student.getClazz().getName() + "%");
16                 }
17                 
18                 if(null != stuNameLike) query.where(stuNameLike);
19                 if(null != clazzNameLike) query.where(clazzNameLike);
20                 return null;
21             }
22         }, new PageRequest(page.getPage() - 1, page.getLimit(), new Sort(Direction.DESC, page.getSortName())));
23     }