springboot专题预计60讲左右,本篇作为第三篇带你5分钟快速完成自定义查询以及分页查询。
一、用@query实现自定义查询操作
首先回忆一下,前面我们创建studentRepo类继承JpaRepository<T,ID>接口,即可实现最基本的crud。如下:
那么我们要自定义查询怎么办呢?如下:
我们定义了两类方法,这两类方法代表Repository使用的一种基本方法,
二、查询方法命名规则一览表
关键字 | 方法命名 | sql where字句 |
---|---|---|
And | findByNameAndPwd | where name= ? and pwd =? |
Or | findByNameOrSex | where name= ? or sex=? |
Is,Equals | findById,findByIdEquals | where id= ? |
Between | findByIdBetween | where id between ? and ? |
LessThan | findByIdLessThan | where id < ? |
LessThanEquals | findByIdLessThanEquals | where id <= ? |
GreaterThan | findByIdGreaterThan | where id > ? |
GreaterThanEquals | findByIdGreaterThanEquals | where id > = ? |
After | findByIdAfter | where id > ? |
Before | findByIdBefore | where id < ? |
IsNull | findByNameIsNull | where name is null |
isNotNull,NotNull | findByNameNotNull | where name is not null |
Like | findByNameLike | where name like ? |
NotLike | findByNameNotLike | where name not like ? |
StartingWith | findByNameStartingWith | where name like '?%' |
EndingWith | findByNameEndingWith | where name like '%?' |
Containing | findByNameContaining | where name like '%?%' |
OrderBy | findByIdOrderByXDesc | where id=? order by x desc |
Not | findByNameNot | where name <> ? |
In | findByIdIn(Collection<?> c) | where id in (?) |
NotIn | findByIdNotIn(Collection<?> c) | where id not in (?) |
True | findByAaaTue | where aaa = true |
False | findByAaaFalse | where aaa = false |
IgnoreCase | findByNameIgnoreCase | where UPPER(name)=UPPER(?) |
三:、@Query配合@Modifying
从名字上可以看到我们的@Query注解好像只是用来查询的,但是如果配合@Modifying注解一共使用,则可以完成数据的删除、添加、更新操作。下面我们来测试下自定义SQL完成删除数据的操作,我根据名字、密码字段共同删除一个数据,接口代码如下图所示:
注意,若看到抛出的异常TranscationRequiredException,意思就是你当前的操作给你抛出了需要事务异常,SpringDataJPA自定义SQL时需要在对应的接口或者调用接口的地方添加事务注解@Transactional该repo类需要添加事务注解@Transactional,来开启事务自动化管理。
四、spring boot的事务
Spring最大的一个优点就是声明式的事务,在原来的开发环境中我们需要在beans.xml中配置事务在哪些类上有作用,现在SpringBoot已经帮助我们完成了这些配置,我们仅仅需要加几个注解就可以解决问题。
那么Spring boot是怎么做的事务处理呢?SpringDataJPA的CrudRepository,JPARepository等默认接口的实现类是SimpleJpaRepository(如下图),大家可以看一下这个代码,我们会发现这些方法已经自动添加了事务处理。
五、分页排序查询原理:
首先,回忆一下JPA体系图,如下
在Spring Data JPA中实现分页需要用到三个接口
PagingAndSortingRepository是spring data jpa实现分页的工厂
第二个findAll
方法就是实现分页的方法,参数是Pageable
类型,同参数传入当前的分页对象(如:第几页,每页多少条记录,排序信息等),查询完成之后会返回一个Page
的对象。Page
对象中就存储了所有的分页信息。Pageable的源码如下
Pageable是一个接口,它的实现类是PageRequest
,PageRequest有三个构造方法
Page
实现了一个Slice的接口,通过这个接口获取排序之后的各个数值,这些方法都比较直观,通过名称就差不多知道该是什么样的一个操作了,大家可以自行查阅一下Page和Slice的源码,这里就不列出了。
六、分页查询实操:
接下实现以下分页的操作, 创建一个StudentPageRepository
来实现分页操作。
虽然PagingAndSortingRepository接口中只有findAll方法,但是我们依然可以使用Repository中的衍生查询,我们只要把Pageable放到最后一个参数即可。测试代码
分页的方法非常的简单即可完成。
七、排序查询实操:
下面我们来实现一下排序的操作,排序和分页类似,我们需要传递一个Sort对象进去,Sort
是一排序类,首先有一个内部枚举对象Direction
,Direction
中有两个值ASC和DESC
分别用来确定升序还是降序,Sort
还有一个内部类Order
,Order
有有两个比较重要的属性Sort.Direction
和property
,第一个用来确定排序的方向,第二个就是排序的属性。
Sort
有如下几个构造函数
排序的代码
七、分页+排序查询:
如果希望在分页的时候进行排序,一样也非常容易,看一下下面PageReques的构造函数
看到这里我相信大家已经会各种排序操作了,这里就不演示了,但是在实际的开发中我们还需要对排序和分页操作进行一下封装,让操作更方便一些,这个话题我们在后面的章节再来详细介绍。