zoukankan      html  css  js  c++  java
  • Spring Data JPA之分页查询

    一、普通:分页+排序

    因为PagingAndSortingRepository,我们总是可以传入Sort和Pageable对查询结果进行排序和分页(derived query、example查询和@Query查询都支持)。

    // 当查询方法中有多个参数的时候,Pageable/Sort建议做为最后一个参数传入
    
    @Query("select u from User u")
    Page<User> findALL(Pageable pageable);
    
    Page<User> findByNickName(String nickName, Pageable pageable);
    
    // 可以返回Page<T>对象,也可以返回List<T>对象

    由于JPA(JPQL)不支持Limit,请采用其他方法实现limit需求,https://stackoverflow.com/questions/44565820/what-is-the-limit-clause-alternative-in-jpql 

    二、单表:分页 + 排序 + 动态查询

    1. repository继承JpaSpecificationExecutor<T>接口;
      • 最终调用Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable)实现“分页+排序”功能
    2. 构造Specification<T> spec;
      • 搜索Specification能得到很多网页结果
        interface Specification<T> {
            Predicate toPredicate(Root<T> root, CriteriaQuery query, CriteriaBuilder cb);
        }
    3. 构造Pageable pageable,
      • Pageable是可以带Sort的
        Pageable sortedByName = 
          PageRequest.of(0, 3, Sort.by("name"));
         
        Pageable sortedByPriceDesc = 
          PageRequest.of(0, 3, Sort.by("price").descending());
         
        Pageable sortedByPriceDescNameAsc = 
          PageRequest.of(0, 5, Sort.by("price").descending().and(Sort.by("name")));
    4. 等待补充

    三、多表:分页 + 排序 + 动态查询

    1. 选择主表
      • 一般选择带“排序字段”的表作为主表,最终的目的是“分页+排序”只存在于主表
      • 主辅表都可以有“动态查询”
    2. 先操作辅表
      • 对辅表进行动态查询等操作,获取逻辑外键的Set集合;
      • 把辅表查询得到的逻辑外键的Set集合,返回给主表;
    3. 再操作主表
      • 把辅表返回的逻辑外键的Set集合当做一个查询条件
        Predicate predicate = root.get("ip").as(String.class).in(ipCollect);
    4. 完成分页和排序操作
      • 还是利用Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable)完成“分页+排序”操作
    5. 填充辅表字段
      • 对分页结果进行Stream操作,补上辅表的字段信息
      • 最终的pagesize数量不会很大,补充字段的操作性能消耗不会很大;
      • Page<T>的返回结果可以通过在entity中补充@Transient字段,后续进行填充

    三、相关问题:

    1. 最后生成的SQL是什么样子的?
      • 是SQL子查询
    2. 多个表都有排序字段的情况下,怎么确定主表?
      • 根据传入的排序字段名,决定哪张为主表,这种情况发生时,大概率是表结构的设计有问题
    3. 这么做的意义是什么?
      • “面向DB编程” VS “面向对象编程”
      • 业务逻辑尽可能放在代码里实现,而不是SQL中
      • 在互联网开发背景下,更倾向于把DB当中带事务支持的容器,把DB的性能压力解耦到应用层
      • 少手写JPQL/SQL,少用JOIN,可以在数据库字段频繁变更,需求频繁变化的情况下,提高开发效率
    4. 这个方案有什么不好的地方吗?
      • JPA在没有物理外键的情况下,无法构建级联关系,这个方法确实可用,但不优雅
    5. 待补充
  • 相关阅读:
    vue element-admin 清空校验
    vue+elementui 动态改变表单必填项
    什么是中台
    项目中遇到的一道算法题
    【解决】Word中公式突然乱码
    【解决】MATLAB报错:此上下文中不支持函数定义,请在代码文件中创建函数。
    【解决】Word打印成PDF出错:%%[ ProductName: Distiller ]%%
    Bike Sharing Analysis(二)- 假设检验方法
    Bike Sharing Analysis(一)- 探索数据
    Spark Structured Streaming(二)实战
  • 原文地址:https://www.cnblogs.com/echo1937/p/13151837.html
Copyright © 2011-2022 走看看