两行代码玩转Spring Data排序和分页
一:唠嗑
在实际项目中对Spring Data的各种使用相当多,简单的增删改查Spring Data提供了现成的方法,一些复杂的,我们可以在接口方法写And,Not等关键字来搞定,想写原生SQL,CQL(Neo4j),Query DSL (Elasticsearch)的,直接使用@Query(“......”)注解搞定,真的是方便到不行!
本篇博客不打算讲Spring Data如何使用,不同的模块(JPA,Neo4j....)使用也略不相同,但Spring Data的排序Sort和分页Pageable接口都是差不多的,所以带大家搞明白搞明白Spring Data的排序和分页是如何使用的。
二:介绍
Spring Data的任务是为数据访问提供一个熟悉的、一致的、基于Spring的编程模型,同时仍然保留底层数据存储的特殊特性。
Spring Data 项目的目的是为了简化构建基于 Spring 框架应用的数据访问计数,包括非关系数据库、Map-Reduce 框架、云数据服务等等;另外也包含对关系数据库的访问支持。
SpringData让数据访问变得更加方便。
三:模块
- Spring Data for Apache Cassandra
- Spring Data Commons
- Spring Data Couchbase
- Spring Data Elasticsearch
- Spring Data Envers
- Spring Data for Pivotal GemFire
- Spring Data Graph
- Spring Data JDBC
- Spring Data JDBC Extensions
- Spring Data JPA
- Spring Data LDAP
- Spring Data MongoDB
- Spring Data Neo4J
- Spring Data Redis
- Spring Data REST
- Spring Data for Apache Solr
- Spring for Apache Hadoop
四:排序
通过一行代码就可以快速使用:
Sort sort = new Sort(Sort.Direction.DESC, "id");
在Sort类中定义了一个枚举类型Direction,该枚举类型声明了两个常量ASC,DESC定义方向。该构造方法的第一个参数指明方向降序(DESC)或升序(ASC),第二个参数指明以id列的值为准进行排序。
你也可以创建一个多属性的Sort实例。
Sort(Sort.Direction direction, List<String> properties)
你也可以只传入属性而不声明方向:
Sort(String... properties)
不过官方已经弃用该方法,推荐使用
public static Sort by(String... properties)
当你不声明方向时,默认方向为升序。
public static final Direction DEFAULT_DIRECTION = Direction.ASC;
Sort的一些方法
| 修饰符和类型 | 方法和描述 |
|---|---|
Sort |
and(Sort sort) 返回由当前排序的排序顺序与给定的排序顺序组成的新排序。 |
Sort |
ascending() 返回具有当前设置但升序方向的新排序。 |
static Sort |
by(List<Sort.Order> orders) 为给定的 Sort.Order创建一个新的排序。 |
static Sort |
by(Sort.Direction direction, String... properties)创建一个新的排序。 |
static Sort |
by(Sort.Order... orders)Creates a new Sort for the given Sort.Orders. |
static Sort |
by(String... properties)Creates a new Sort for the given properties. |
Sort |
descending() 返回具有当前设置但顺序相反的新排序。 |
boolean |
equals(Object obj) |
Sort.Order |
getOrderFor(String property)根据property获取Order |
boolean |
isSorted() |
boolean |
isUnsorted() |
Iterator<Sort.Order> |
iterator() |
static Sort |
unsorted() 返回一个根本没有排序设置的排序实例。 |
Sort.Order
Sort.Order是Sort的一个静态内部类,官方说明是:PropertyPath实现了排序的配对。方向和属性。它用于提供排序的输入 。
简单来讲,你可以定义一个Order,在需要时传入order构建Sord实例。
Order(Sort.Direction direction, String property)
更独特的使用是加入自己的空处理提示的枚举:
Order(Sort.Direction direction, String property, Sort.NullHandling nullHandlingHint)
Sort.NullHandling是可用于排序表达式的空处理提示的枚举。对使用的数据存储的一种提示,用于在非空条目之后对具有空值的条目进行排序。
在需要Sort时,可通过Order创建:
Sort(Sort.Order... orders)
Sort.Order的一些方法
| 修饰符和类型 | 方法和描述 |
|---|---|
static Sort.Order |
asc(String property)创建升序的Order实例 |
static Sort.Order |
by(String property)创建默认方向的Order实例 |
static Sort.Order |
desc(String property)创建降序的Order实例 |
Sort.Direction |
getDirection() |
Sort.NullHandling |
getNullHandling() |
String |
getProperty() |
Sort.Order |
ignoreCase()开启不分大小写排序 |
boolean |
isAscending()返回此属性的排序是否要升序。 |
boolean |
isDescending()返回此属性的排序是否应该降序。 |
boolean |
isIgnoreCase()返回该排序是否区分大小写。 |
Sort.Order |
nullsFirst()返回 Sort.Order 使用 Sort.NullHandling.NULLS_FIRST 作为空处理提示。First:第一个 |
Sort.Order |
nullsLast()返回 Sort.Order 使用Sort.NullHandling.NULLS_LAST 作为空处理提示。Last:最后一个 |
Sort.Order |
nullsNative()返回 Sort.Order 使用Sort.NullHandling.NATIVE 作为空处理提示。NATIVE:原生的 |
Sort.Order |
with(Sort.Direction direction)创建Order实例. |
Sort.Order |
with(Sort.NullHandling nullHandling)创建Order实例. |
Sort |
withProperties(String... properties)创建Order实例. |
Sort.Order |
withProperty(String property)创建Order实例. |
如果你还想全面了解它的使用,推荐阅读官方英文文档:https://docs.spring.io/spring-data/data-commons/docs/current/api/org/springframework/data/domain/Sort.html
五:分页
Pageable只是 Spring Data 提供的分页信息的抽象接口。
实现类:
AbstractPageRequest:抽象类。供PageRequest和QPageRequest继承。
PageRequest: 基本的可页面化Java Bean实现。
QPageRequest:基本的Java Bean实现,可以支持QueryDSL。
分页功能也只需要一行代码:
Pageable pageable = new PageRequest(int page, int size, Sort sort);
page - 从零开始的索引页
size- 要返回的页面的大小
sort - 排序
你也可以创建没有排序的分页
PageRequest(int page, int size)
更方便的是可以一行代码创建有排序方向和属性的分页
PageRequest(int page, int size, Sort.Direction direction, String... properties)
如果你使用的是2.0以后的版本,官方已经弃用以上构造方法的形式,推荐使用静态方法:
| 修饰符和类型 | 方法和描述 |
|---|---|
static PageRequest |
of(int page, int size) |
static PageRequest |
of(int page, int size, Sort.Direction direction, String... properties) |
static PageRequest |
of(int page, int size, Sort sort) |
比如我们想遍历整个数据表,就可以使用分页遍历,这样不至于一次把数据全部加载到内存。
| 修饰符和类型 | 方法和描述 |
|---|---|
Pageable |
first() 请求第一页。 |
Sort |
getSort() 返回排序参数。 |
Pageable |
next() 请求下一个页面。 |
PageRequest |
previous() 请求前一页。 |
注意:在使用next()方法时,不要把pageable.next()直接作为参数传入方法,如repository.findAll(page.next())这样的写法会导致死循环。查看next()方法的源码发现这个方法只是帮我们new了一个新的Pageable对象,原来的pageable还是没啥变化。一直next()下去也只是在原地踏步。
public Pageable next() {
return new PageRequest(getPageNumber() + 1, getPageSize(), getSort());
}
正确的写法:
repository.findAll(pageable = pageable.next());
六:使用
Spring Data Jpa除了会通过命名规范帮助我们扩展Sql语句外,还会帮助我们处理类型为Pageable的参数,将pageable参数转换成为sql语句中的条件,同时,还会帮助我们处理类型为Page的返回值,当发现返回值类型为Page,Spring Data Jpa将会把数据的整体信息、当前数据的信息,分页的信息都放入到返回值中。这样,我们就能够方便的进行个性化的分页查询。
public interface UserRepository extends JpaRepository<User,Long> {
@Override
Page<Medical> findAll(Pageable pageable);
}
如果你想用@Query写原生查询语句并实现分页:
Spring Data JPA目前不支持原生查询的动态排序,因为它必须操作声明的实际查询,这对于原生SQL是无法可靠地做到的。但是,您可以通过自己指定count查询来使用原生查询进行分页,如下面的示例所示:
public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",
countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
nativeQuery = true)
Page<User> findByLastname(String lastname, Pageable pageable);
}
七:读取
分页查询:
Page<Book> sampleEntities = userRepository.findAll(pageable);
接口Page继承了接口Slice,话不多说,直接上干货!
总页数
int getTotalPages()
元素的总数
long getTotalElements()
返回当前页的索引(是第几页)
int getNumber()
返回作为List的页面内容
List<T> getContent()
返回当前在这个页上的元素的数量
int getNumberOfElements()
返回用于请求当前页的Pageable
default Pageable getPageable()
返回页的大小。
int getSize()
返回页的排序参数。
Sort getSort()
页面是否有内容。
boolean hasContent()
是否有下一页。
boolean hasNext()
是否有上一页
boolean hasPrevious()
当前页是否是第一个
boolean isFirst()
当前页是否是最后一个
boolean isLast()
下一页的Pageable
Pageable nextPageable()
上一页的Pageable
Pageable previousPageable()
关于Spring Data的排序与分页就到这里,记得点赞哦~~~
本文已授权微信公众号“后端技术精选”独家发布
两行代码玩转Spring Data排序和分页的更多相关文章
- 两行代码玩转SUMO!
两行代码玩转SUMO! 这篇博客很简单,但是内容很丰富 如何生成如下所示的研究型路网结构? 只需要打开ubuntu终端输入如下代码即可,grid.number代表路口数量,grid.length代表路 ...
- Spring Data Jpa:分页、Specification、Criteria
分页的主要接口与类 PagingAndSortingRepository 继承自 CrudRepository 接口,提供了排序以及分页查询能力,提供了两个方法 Iterable<T> f ...
- Spring Data Jpa 实现分页(Spring MVC+easyui)
spring data jpa很好的对dao层进行了封装,这篇文章主要来写的是实现easyui datagird数据分页,由于各个UI参数不大一样,所以如果使用的是其他UI,得稍作修改.需要说明的是我 ...
- 【JPA】Spring Data JPA 实现分页和条件查询
文章目录 1.在`Repository`层继承两个接口 2.在Service层进行查询操作 3.Page的方法 1.在Repository层继承两个接口 JpaRepository<Admin, ...
- 关于Spring Data JPA更新部分字段的问题
1.问题背景 个人比较喜欢Spring data JPA,这次的问题是在实体类中使用List类型作为字段,JPA也提供了操作的方法,即使用@ElementCollection注解,网上对于JPA的知识 ...
- 整合Spring Data JPA与Spring MVC: 分页和排序
之前我们学习了如何使用Jpa访问关系型数据库.比较完整Spring MVC和JPA教程请见Spring Data JPA实战入门,Spring MVC实战入门. 通过Jpa大大简化了我们对数据库的开发 ...
- 使用Spring Data JPA进行数据分页与排序
一.导读 如果一次性加载成千上万的列表数据,在网页上显示将十分的耗时,用户体验不好.所以处理较大数据查询结果展现的时候,分页查询是必不可少的.分页查询必然伴随着一定的排序规则,否则分页数据的状态很难控 ...
- 整合Spring Data JPA与Spring MVC: 分页和排序pageable
https://www.tianmaying.com/tutorial/spring-jpa-page-sort Spring Data Jpa对于分页以及排序的查询也有着完美的支持,接下来,我们来学 ...
- Spring Data REST PATCH请求 远程代码执行漏洞案例(CVE-2017-8046)
恶意的PATCH请求使用精心构造的JSON数据提交到spring-data-rest服务可以执行任意JAVA代码 1. 背景 Spring Data REST是Spring Data项目的一部分,可以 ...
随机推荐
- Linux中对swap分区的配置
swap分区的安装与正常分区的安装大致相同,我这里就只说一下不同 大家可先看我上一篇的安装:https://www.cnblogs.com/feiquan/p/9219447.html 1.查看swa ...
- SQL Server中如何识别、查找未使用的索引(unused indexes)
在SQL Server中,索引是优化SQL性能的一大法宝.但是由于各种原因,索引会被当做"银弹"滥用,一方面有些开发人员(甚至是部分数据库管理员)有一些陋习,不管三七二十一,总是根 ...
- Windows四大傻X功能——那些拖慢系统性能的罪魁祸首
最近新装了一个PC,配置还算蛮高,i7的CPU,8G内存,2T的硬盘,于是小心翼翼地装了一个干净的正版Win7,但是发现居然开机明显卡?所以做了些研究,发现即使全新安装的正版windows,居然也有些 ...
- Linux下键盘值 对应input_evnet的code值。
最近做了一个linux下面的模拟鼠标和键盘的app,但不是很清楚字符对应的键值:查找内核源码,在kernel/include/uapi/linux/input.h文件中找到: 下面给出普通键盘上面对应 ...
- LeetCode算法题-Sum of Two Integers(Java实现)
这是悦乐书的第210次更新,第222篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第78题(顺位题号是371).计算两个整数a和b的总和,但不允许使用运算符+和 - .例 ...
- JavaScript中的Generator函数
1. 简介 Generator函数时ES6提供的一种异步编程解决方案.Generator语法行为和普通函数完全不同,我们可以把Generator理解为一个包含了多个内部状态的状态机. 执行Genera ...
- python 之常用模块
一 认识模块 二 常用模块 (1)re模块 (2)collections模块 一 认识模块 (1)什么是模块 (2)模块的导入和使用 (1)模块是:一个模块就是一个包含 ...
- localhost和127.0.0.1及ip区别
1.127.0.0.1是回送地址,指本地机,一般用来测试使用.回送地址是本机回送地址(Loopback Address),即主机IP堆栈内部的IP地址,主要用于网络软件测试以及本地机进程间通信,无论什 ...
- [tool] AI视频翻译 解决英文视频字幕问题(类似youtube自动生成字幕)
1.网易见外是网易人工智能事业部旗下的AI视频翻译产品. 字幕支持手工编辑和下载 不过网易见外 只支持WEB在线操作 并且只支持单个上传操作 目前没有客户端 2.人人译视界 (IOS 安卓 PC客户端 ...
- java让数字显示千分位 mark
/** * 格式化数字为千分位显示: * @param 要格式化的数字: * @return */ public static String fmtMicrometer(String text) { ...