Spring JPA find分页示例详解

目录
  • 前言
  • 源码
  • 一、单纯分页查询
    • 查询结果
    • 结论
  • 二、排序分页查询
    • 查询结果
  • 三、方法整理
  • 总结:

前言

在现实项目中,数据量一般都不小,如果一次性全部请求出来,肯定是影响性能,而且大量数据展示到页面上观感也不好。这时我们就需要用到分页,给定一个 pageSize,每次请求的数量就是 pageSize 的大小,这样既可以节约时间,又可以美化页面。Spring JPA 就为我们提供这样一个方法,准确来说是提供了一个对象用来约束数据按照分页的形式进行请求。

源码

findAll(Pageable pageable):从入参 pageable 我们可以猜到,就是这个对象来帮助我们对数据进行分页查询。那我们如何创建 pageable 对象呢?如何用他去实现分页呢?先看一下源码:

/**
 * Creates a new {@link Pageable} for the first page (page number {@code 0}) given {@code pageSize} .
 *
 * @param pageSize the size of the page to be returned, must be greater than 0.
 * @return a new {@link Pageable}.
 * @since 2.5
 */
static Pageable ofSize(int pageSize) {
   return PageRequest.of(0, pageSize);
}

由此可见,pageable 对象需要 pageRequest.of 去创建,那我们再看看 pageRequest.of 的源码:

/**
 * Creates a new unsorted {@link PageRequest}.
 *
 * @param page zero-based page index, must not be negative.
 * @param size the size of the page to be returned, must be greater than 0.
 * @since 2.0
 */
public static PageRequest of(int page, int size) {
   return of(page, size, Sort.unsorted());
}
/**
 * Creates a new {@link PageRequest} with sort parameters applied.
 *
 * @param page zero-based page index.
 * @param size the size of the page to be returned.
 * @param sort must not be {@literal null}, use {@link Sort#unsorted()} instead.
 * @since 2.0
 */
public static PageRequest of(int page, int size, Sort sort) {
   return new PageRequest(page, size, sort);
}
/**
 * Creates a new {@link PageRequest} with sort direction and properties applied.
 *
 * @param page zero-based page index, must not be negative.
 * @param size the size of the page to be returned, must be greater than 0.
 * @param direction must not be {@literal null}.
 * @param properties must not be {@literal null}.
 * @since 2.0
 */
public static PageRequest of(int page, int size, Direction direction, String... properties) {
   return of(page, size, Sort.by(direction, properties));
}

从源码可以看出,pageRequest.of 需要传入 page(第几页)和 size(页面大小),另外如果需要排序的话,还需要传入 sort(这个对象前一篇已经分析过了)。

一、单纯分页查询

所谓的单纯分页查询,就是只分页,不做其他的动作,这样一来,我们只需要传入 pagepageSize 即可。
control 层

@GetMapping("findAllPage")
public Page<User> findAllPage(int page, int pageSize) {
    Pageable pageable = PageRequest.of(page, pageSize);
    return userService.findAllPage(pageable);
}

执行请求findAllPage?page=0&pageSize=5(第一页、页面大小为5),控制台打印如下:

Hibernate: select user0\_.id as id1\_0\_, user0\_.age as age2\_0\_, user0\_.name as name3\_0\_ from user user0\_ limit ?
Hibernate: select count(user0\_.id) as col\_0\_0\_ from user user0\_

查询结果

{
    "content": [{
                    "id": 20,
                    "name": "aa",
                    "age": 11
            }, {
                    "id": 21,
                    "name": "bb",
                    "age": 12
            }, {
                    "id": 22,
                    "name": "cc",
                    "age": 11
            }, {
                    "id": 23,
                    "name": "dd",
                    "age": 16
            }, {
                    "id": 24,
                    "name": "ee",
                    "age": 17
            }
    ],
    "pageable": {
            "sort": {
                    "empty": true,
                    "sorted": false,
                    "unsorted": true
            },
            "offset": 0,
            "pageSize": 5,
            "pageNumber": 0,
            "unpaged": false,
            "paged": true
    },
    "last": false,
    "totalPages": 2,
    "totalElements": 6,
    "number": 0,
    "size": 5,
    "sort": {
            "empty": true,
            "sorted": false,
            "unsorted": true
    },
    "numberOfElements": 5,
    "first": true,
    "empty": false
}

结论

从上面的结果输出和控制台输出来看,它除了做了 limit 分页查询外,还做了求出了总数totalElements,还输出了总页数 totalPages。这些参数在我们实际项目中有的时候还是很有用的。

二、排序分页查询

所谓的排序分页,就是将数据先按照我们所需的方式进行排序,然后再进行分页查询
control 层

@GetMapping("findAllPageSort")
public Page<User> findAllPageSort(int page, int pageSize, String[] sorts, String[] paras) {
    List<Sort.Order> listOrder = new ArrayList<>();
    for(int i=0; i<sorts.length; i++){
        listOrder.add(new Sort.Order(sorts[i].toLowerCase().equals("asc") ?
                Sort.Direction.ASC : Sort.Direction.DESC, paras[i]));
    }
    Pageable pageable = PageRequest.of(page, pageSize, Sort.by(listOrder));
    return userService.findAllPage(pageable);
}

执行请求findAllPageSort?page=0&pageSize=5&sorts=asc,desc&paras=age,name(第一页,页面大小为5,先按照age升序,再按照name降序),控制台打印如下:

Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_ from user user0_ order by user0_.age asc, user0_.name desc limit ?
Hibernate: select count(user0_.id) as col_0_0_ from user user0_

查询结果

{
	"content": [{
			"id": 26,
			"name": "gg",
			"age": 7
		}, {
			"id": 22,
			"name": "cc",
			"age": 11
		}, {
			"id": 20,
			"name": "aa",
			"age": 11
		}, {
			"id": 21,
			"name": "bb",
			"age": 12
		}, {
			"id": 23,
			"name": "dd",
			"age": 16
		}
	],
	"pageable": {
		"sort": {
			"empty": false,
			"sorted": true,
			"unsorted": false
		},
		"offset": 0,
		"pageNumber": 0,
		"pageSize": 5,
		"paged": true,
		"unpaged": false
	},
	"totalElements": 7,
	"last": false,
	"totalPages": 2,
	"number": 0,
	"size": 5,
	"sort": {
		"empty": false,
		"sorted": true,
		"unsorted": false
	},
	"numberOfElements": 5,
	"first": true,
	"empty": false
}

三、方法整理

以下是整理的 pageable 对象可用的一些比较实用的方法

方法 说明
boolean unpaged true:未进行分页,false:进行了分页
boolean isPaged true:进行了分页,false:未进行分页
int getPageNumber 获取当前页数
int getPageSize 获取页面大小
long getOffSet 获取页面偏移量,相当于sql中的start
Sort getSort 获取当前的排序规则
Pageable next 获取下一页的分页信息(翻页中的下一页)
boolean hasPrevious 是否有上一页
Pageable previous 获取上一页的分页信息(翻页钟的上一页)
Pageable first 获取首页分页信息
Pageable previousOrFirst 如果没有上一页则回到首页

总结:

分页查询是实际项目中非常常见的需求,总体上看也没有什么比较难的地方,需要注意的就是排序了。到目前为止学习的都是JpaRepository自带的一些接口,下面我们就开始接触非自带的需要我们自己去构造的方法了。

以上就是Spring JPA find分页示例详解的详细内容,更多关于Spring JPA find分页的资料请关注我们其它相关文章!

(0)

相关推荐

  • Spring JPA之save方法示例详解

    目录 一.save(单条添加) 源码 service 层 control层 二.saveAll(批量添加) 源码 service control层 一.save(单条添加) 源码 @Transactional @Override public <S extends T> S save(S entity) { Assert.notNull(entity, "Entity must not be null."); if (entityInformation.isNew(enti

  • Spring JPA联表查询之注解属性详解

    目录 前言 一.targetEntity 二.cascade 1.不定义 2.CascadeType.PERSIST 3.CascadeType.REMOVE 4.CascadeType.REFRESH 5.CascadeType.MERGE 6.CascadeType.ALL 三.fetch FetchType.LAZY FetchType.EAGER 四.mappedBy 五.orphanRemoval 前言 对于联表查询的四个注解 @OneToOne.@OneToMany.@ManyToO

  • Spring JPA学习之delete方法示例详解

    目录 一.deleteById 和 delete deleteById(Id id)(通过id进行删除) delete(T entity)(通过实体对象进行删除) 实例 service 层 control层 二.deleteAllById 和 deleteAll 1.deleteAllById(Iterable<? extends ID> ids)(通过id进行批量删除) 2.deleteAll(Iterable<? extends T> entities)(通过实体对象进行批量删

  • Spring JPA find单表查询方法示例详解

    目录 一.findById(ID id) 二.findAll() 三.findAllById(Iterable<ID> ids) 四.findAll(Sort sort) 单调排序 sort.by 源码 control层 五.findAll(Sort sort) 多参数排序 Sort by 源码 control 层 总结 一.findById(ID id) 通过id进行单条查询,先看看 findById(ID id) 的源码 @Override public Optional<T>

  • Spring JPA联表查询之OneToOne源码详解

    目录 前言 源码 注解属性 单向联表 user 实体类 car 实体类 查询结果 双向联表 user 实体 car 实体 查询结果 延迟加载(懒加载) user 实体 查询结果: 查询完会发现,控制台又打印了一个 JPQL: 最后结论 前言 前面几篇我们学习的都是单表查询,就是对一张表中的数据进行查询.而实际项目中,基本都会有多张表联合查询的情况,今天我们就来了解下JPA的联表查询是如做的. 源码 @OneToOne 注解实现一对一关系映射.比如用户跟车辆的关系(这里假设一个人只能有一辆车),一

  • Spring JPA之find拓展方法示例详解

    目录 前言 一.单条件查询 1.精确查询(确定值,例如:=.is) 2.范围查询(一定范围,例如<.<=.>.>=.in.between) a)运算符 b)between c)in 3.模糊查询 a)findByNameLike b)findByNameStartingWith 二.多条件查询 三.关键字 最后总结: 前言 前两篇我们详细了解了 findById 和 findAll 以及 findAll 的分页查询,如果说JPA只有上面的两种查询功能,那就太low了,今天让我们再深

  • Spring JPA find分页示例详解

    目录 前言 源码 一.单纯分页查询 查询结果 结论 二.排序分页查询 查询结果 三.方法整理 总结: 前言 在现实项目中,数据量一般都不小,如果一次性全部请求出来,肯定是影响性能,而且大量数据展示到页面上观感也不好.这时我们就需要用到分页,给定一个 pageSize,每次请求的数量就是 pageSize 的大小,这样既可以节约时间,又可以美化页面.Spring JPA 就为我们提供这样一个方法,准确来说是提供了一个对象用来约束数据按照分页的形式进行请求. 源码 findAll(Pageable

  • Spring容器刷新obtainFreshBeanFactory示例详解

    目录 Spring容器刷新—02—obtainFreshBeanFactory BeanFactory和ApplicationContext obtainFreshBeanFactory 1.GenericApplicationContext系列的实现 2.AbstractRefreshableApplicationContext系列的实现 该使用哪个BeanFactory? Servlet环境 SpringBoot环境 Spring容器刷新—02—obtainFreshBeanFactory

  • jQuery pagination分页示例详解

    本文实例为大家分享了jQuery pagination分页示例的具体代码,供大家参考,具体内容如下 前台html <!doctype html> <html> <head> <meta charset="utf-8"> <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" id="v

  • Spring中统一异常处理示例详解

    前言 系统很多地方都会抛出异常, 而Java的异常体系目标就是与逻辑解耦,Spring提供了统一的异常处理注解,用户只需要在错误的时候提示信息即可 在具体的SSM项目开发中,由于Controller层为处于请求处理的最顶层,再往上就是框架代码的. 因此,肯定需要在Controller捕获所有异常,并且做适当处理,返回给前端一个友好的错误码. 不过,Controller一多,我们发现每个Controller里都有大量重复的.冗余的异常处理代码,很是啰嗦. 能否将这些重复的部分抽取出来,这样保证Co

  • Spring条件注解@Conditional示例详解

    前言 @Conditional是Spring4新提供的注解,它的作用是根据某个条件创建特定的Bean,通过实现Condition接口,并重写matches接口来构造判断条件.总的来说,就是根据特定条件来控制Bean的创建行为,这样我们可以利用这个特性进行一些自动的配置. 本文将分为三大部分,@Conditional源码的介绍.Condition的使用示例和@Conditional的扩展注解的介绍. 一.@Conditional的源码 @Target({ElementType.TYPE, Elem

  • Spring MVC异常处理机制示例详解

    前言 在Spring MVC中,当一个请求发生异常(Controller抛出一个异常时), DispatcherServlet 采用委托的方式交给一个处理链来处理或者解析这个抛出的异常,这是在request和Servlet Container之间的一道屏障,所以我们可以在这里做一些处理工作,如转换异常,转换成友好的error page或者http 状态码等. 核心接口 这个处理机制在Spring是以HandlerExceptionResolver接口为核心的,该接口只有一个处理方法: Model

  • Spring data jpa的使用与详解(复杂动态查询及分页,排序)

    一. 使用Specification实现复杂查询 (1) 什么是Specification Specification是springDateJpa中的一个接口,他是用于当jpa的一些基本CRUD操作的扩展,可以把他理解成一个spring jpa的复杂查询接口.其次我们需要了解Criteria 查询,这是是一种类型安全和更面向对象的查询.而Spring Data JPA支持JPA2.0的Criteria查询,相应的接口是JpaSpecificationExecutor. 而JpaSpecifica

  • Spring Data JPA注解Entity使用示例详解

    目录 1.JPA协议中关于Entity的相关规定 需要注意的是: 2.常用注解 2.1 JPA支持的注解 2.2 常用注解 3.联合主键 3.1 @IdClass 3.2 @Embeddable与@EmbeddedId注解使用 3.3 两者的区别是什么? 1.JPA协议中关于Entity的相关规定 (1)实体是直接进行数据库持久化操作的领域对象(即一个简单的POJO),必须通过@Entity注解进行标示. (2)实体必须有一个 public 或者 projected的无参数构造方法. (3)持久

  • Spring Data JPA系列JpaSpecificationExecutor用法详解

    目录 1.JpaSpecificationExecutor用法 2.JpaSpecificationExecutor语法详解 2.1 Specification 接口 2.2 Root< User >root 2.3 CriteriaQuery<?> query 2.4 CriteriaBuilder cb 在上一篇文章中,我们介绍了QueryByExampleExecutor动态查询的方法,那么今天我们来学习JpaSpecificationExecutor的详细用法. 1.Jpa

随机推荐