Spring Data Jpa 学习笔记
官网 ;https://docs.spring.io/spring-data/jpa/reference/index.html
一、spring Data Jpa 介绍
Jpa : JPA(Java Persistence API)是用于在Java应用程序中进行对象持久化的API,用于描述对象-关系映射(ORM)规范(就像java的JDBC规范,每个数据库厂商都有对应的实现)。
Hibernate :Hibernate 是一个流行的开源对象-关系映射(ORM)框架,它实现了JPA(Java Persistence API)规范,为Java应用程序提供了数据持久化的解决方案。
Spring Data JPA:Spring Data JPA 是 Spring 框架中的一个模块,它简化了对于基于 JPA (Java Persistence API) 的数据访问层的开发。JPA 是 Java EE 中用于对象持久化的标准,而 Spring Data JPA 则在其基础上提供了一系列便捷的功能,帮助开发者更轻松地与数据库进行交互。
Spring Data: Spring Data是Spring生态中的一个项目,目标就是简化对数据访问的开发,个人觉得spring的野心很大,它并不限于关系型数据库,还支持文档型数据库,NoSQL数据库。
简单来说 Spring Data Jpa 是spring对Jpa规范的在一次封装,目的就是简化数据库操作。最大特点就是
Defining Query Methods定义查询方法。第一次接触的时候感觉很神奇。通过对方法名的解析就能自动生成查询语句。
二、快速入门
- 引入maven坐标
1 |
|
- 创建实体类 和 repository接口 还有启动类的开启Jpa ,代码中对应解释
1 |
|
- 我们测试一下看看结果
1 |
|
三、核心接口
Spring Data抽象出来的顶层接口是 Repository
。 直接或间接实现这个接口才有操作数据的能力,不限于关系型数据库,还支持Redis ,MangoDB等。
Spring data jpa 通过解析方法名自动去生成查询sql。为了简化开发者开发,也提供了一些带有常用查询方法的接口,我们只需要直接实现就可以使用。例如CrudRepository ,ListCrudRepository ,JpaRepository,PagingAndSortingRepository等接口,每一个接口都补充了一些特定的功能下面是我在idea中查看的关系图,
3.1 CrudRepository接口 增删改查接口
对比实现普通Repository和CrudRepository,看一看UserRepository会发生什么变化
- 实现Repository。
- 实现CrudRepository
- 总结,CrudRepository就和我们自己定义的repository是一样的原理,只不过声明好了一些通用的方法,搭配泛型就可以复用一些通用的操作.看一下源码
1 |
|
- @NoRepositoryBean: 因为继承了repository接口spring会认为他也是一个bean,实际并不是只是中间扩展接口,所以使用@NoRepositoryBean标识一下 就不会当作Bean处理了
支持分页接口
3.2 PagingAndSortingRepository 分页排序接口
- 使用的时候直接继承这个接口即可,声明一个方法返回结果为 page 字面意思理解就是
-
package chances.learn.jpa.repo; import chances.learn.jpa.entity.Person; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.Repository; import java.util.Optional; public interface PersonRepository extends CrudRepository<Person, Long>, PagingAndSortingRepository<Person,Long> { Person save(Person person); Page<Person> findAll(String name, Pageable pageable); Optional<Person> findById(long id); }
1
2
3
4
5
6
7
8
9
10
11
12
132. 开始unit test ,创建分页查询条件时候 使用PageRequest.of方法 。看看数据库和结果。
1. ![img](https://chances.feishu.cn/space/api/box/stream/download/asynccode/?code=MTliOTRmNmQyMDA0ZDZlNGQ2NzFiNjMyYjQ2OWU5YjFfenZtMFJzTlg0R3hKNmlWTno4SWcxTWJBZ2xlUkQ3ZkNfVG9rZW46RDdlRmJsMUFOb0tuVlJ4eWxUS2N2YWRhbjJkXzE3MTQ5MDIzMzg6MTcxNDkwNTkzOF9WNA)
2. ![img](https://chances.feishu.cn/space/api/box/stream/download/asynccode/?code=ZTI4YmM1NzA2ZGExMzMzYzE0ZDZhYTUyYTliYmM2YjBfUGhyOUMzUERzQU1XMFZKZk9vWVljM0Ezb3lpSWNiZFRfVG9rZW46TFVCamJmbWpZb3BnaTZ4MXFPcWNFa3hzbmNoXzE3MTQ5MDIzMzg6MTcxNDkwNTkzOF9WNA)
3. ```Java
@Test
void page() {
//每页两条 第一页 按照age降序
Sort sort = Sort.by(Sort.Direction.DESC, "age");
Page<Person> all = personRepository.findAll(PageRequest.of(0, 2));
log.info("page result:{}",all.toString());
}
-
3.3 JpaRepository 整合了常用的数据库操作
通过扩展 JpaRepository
,继承基本的 CRUD(创建、读取、更新、删除)操作,以及使用 Spring Data 的本地查询进行分页、排序方法。这个接口简化了 Spring 应用程序中数据访问层的开发,减少了与数据库操作通常相关的样板代码。
在debug的时候发现一件事情,发现PersonRepository经过动态代理之后已经变成了SimpleJpaRepository类型,
四、Defining Query Methods 定义查询方法(Jpa特色)
Defining Query Method是Jpa的一大特性。定义查询方法有官网说明提供了两种方式。第一种 通过直接从方法名称解析后查询,第二种 通过手动定义方式的来执行。
简单示例
1 |
|
4.1 Query Lookup Strategies查询查找策略
在 Spring Data JPA 中,有两种主要的方式来定义查询方法:基于方法名的命名约定和使用 @Query
注解定义的自定义查询。查询查找策略决定了 Spring Data JPA 在执行方法时应该优先考虑哪种方式。官网中告诉我们一共有三种选择策略模式,和如何切换查找策略。
CREATE
从方法名解析删除指定的前缀 例如 find,findAll,然后解析方法名的其余部分。也就是直接根据方法名创建查询。如果方法名不符合规则启动会报异常,及时配置了@query
注解USE_DECLARED_QUERY
使用声明好的查询,也就是使用*@query
* 注解声明的查询,如果没找到也会抛出异常。CREATE_IF_NOT_FOUND
这是默认的查找策略,先去使用@Quer
y声明好的查询,如果找不到再去使用通过方法名创建查询。
更改默认的策略修改@EnableJpaRepositories
的queryLookupStrategy属性即可。
1 |
|
4.2 通过方法名解析查询
下面是官网给出的示例,可以看出方法名是通过前缀+字段名+字段描述符+…组成
1 |
|
前缀不仅有find还有 count,delete,remove等其他的前缀。每个版本可能支持的都不一样可以看看Jpa的查询解析语法树看看。 org.springframework.data.repository.query.parser.PartTree
1 |
|