两行代码玩转Spring Data排序和分页

简介: 两行代码玩转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


  • 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的一些方法


image.png


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的一些方法:


image.png


如果你还想全面了解它的使用,推荐阅读官方英文文档:


https://docs.spring.io/spring-data/data-commons/docs/current/api/org/springframework/data/domain/Sort.html

五:分页


Pageable只是 Spring Data 提供的分页信息的抽象接口。


实现类:

  1. AbstractPageRequest:抽象类。供PageRequest和QPageRequest继承。
  2. PageRequest: 基本的可页面化Java Bean实现。
  3. 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以后的版本,官方已经弃用以上构造方法的形式,推荐使用静态方法:



image.png


比如我们想遍历整个数据表,就可以使用分页遍历,这样不至于一次把数据全部加载到内存。



image.png


注意:在使用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()



目录
相关文章
|
7天前
|
Java 数据库连接 API
【Java笔记+踩坑】Spring Data JPA
从常用注解、实体类和各层编写方法入手,详细介绍JPA框架在增删改查等方面的基本用法,以及填充用户名日期、分页查询等高级用法。
【Java笔记+踩坑】Spring Data JPA
|
1月前
|
Java 数据安全/隐私保护 Spring
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
|
20天前
|
Java Spring XML
掌握面向切面编程的秘密武器:Spring AOP 让你的代码优雅转身,横切关注点再也不是难题!
【8月更文挑战第31天】面向切面编程(AOP)通过切面封装横切关注点,如日志记录、事务管理等,使业务逻辑更清晰。Spring AOP提供强大工具,无需在业务代码中硬编码这些功能。本文将深入探讨Spring AOP的概念、工作原理及实际应用,展示如何通过基于注解的配置创建切面,优化代码结构并提高可维护性。通过示例说明如何定义切面类、通知方法及其应用时机,实现方法调用前后的日志记录,展示AOP在分离关注点和添加新功能方面的优势。
30 0
|
20天前
|
Java Spring 数据库
怎样动动手指就能实现数据操作?Spring Data JPA背后的魔法揭秘
【8月更文挑战第31天】在Java开发中,数据库交互至关重要。传统的JDBC操作繁琐且难维护,而Spring Data JPA作为集成JPA的数据访问层解决方案,提供了CRUD等通用操作接口,显著减少代码量。通过继承`JpaRepository`,开发者能轻松实现数据的增删改查,甚至复杂查询和分页也不再困难。本文将通过示例详细介绍如何利用Spring Data JPA简化数据访问层的开发,提升代码质量和可维护性。
26 0
|
20天前
|
Java Spring 容器
彻底改变你的编程人生!揭秘 Spring 框架依赖注入的神奇魔力,让你的代码瞬间焕然一新!
【8月更文挑战第31天】本文介绍 Spring 框架中的依赖注入(DI),一种降低代码耦合度的设计模式。通过 Spring 的 DI 容器,开发者可专注业务逻辑而非依赖管理。文中详细解释了 DI 的基本概念及其实现方式,如构造器注入、字段注入与 setter 方法注入,并提供示例说明如何在实际项目中应用这些技术。通过 Spring 的 @Configuration 和 @Bean 注解,可轻松定义与管理应用中的组件及其依赖关系,实现更简洁、易维护的代码结构。
25 0
|
22天前
|
监控 安全 Java
【开发者必备】Spring Boot中自定义注解与处理器的神奇魔力:一键解锁代码新高度!
【8月更文挑战第29天】本文介绍如何在Spring Boot中利用自定义注解与处理器增强应用功能。通过定义如`@CustomProcessor`注解并结合`BeanPostProcessor`实现特定逻辑处理,如业务逻辑封装、配置管理及元数据分析等,从而提升代码整洁度与可维护性。文章详细展示了从注解定义、处理器编写到实际应用的具体步骤,并提供了实战案例,帮助开发者更好地理解和运用这一强大特性,以实现代码的高效组织与优化。
34 0
|
22天前
|
Java 开发者 Spring
Spring Boot大法好:解耦、隔离、异步,让代码‘活’起来,性能飙升的秘密武器!
【8月更文挑战第29天】解耦、隔离与异步是Spring Boot中的关键设计原则,能大幅提升软件的可维护性、扩展性和性能。本文通过示例代码详细探讨了这些原则的应用:依赖注入和面向接口编程实现解耦;模块化设计与配置文件实现隔离;`@Async`注解和`CompletableFuture`实现异步处理。综合运用这些原则,可以显著提升软件质量和性能,使系统更加健壮、灵活和高效。
22 0
|
30天前
|
存储 Java 数据库
|
30天前
|
存储 Java API
|
30天前
|
Java 数据库连接 数据库
Spring Data JPA 与 Hibernate 之区别
【8月更文挑战第21天】
17 0