您现在的位置是:首页 > 正文

PageHelper 分页查询「实现篇」

2024-01-30 23:19:36阅读 0

两种情况

分两种情况:

  1. 查出来为 PageQueryRespDTO
  2. 查出来直接是 Model

查出来为 PageQueryRespDTO

public PageInfo<PageQueryRespDTO> queryPageList(PageQueryReqDTO dto) {       
    PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
    List<PageQueryRespDTO> result = xxMapper.queryPageList(dto);

    return new PageInfo<>(result);
}

查出来直接是 Model

public PageInfo<PageQueryRespDTO> queryPageList(PageQueryReqDTO dto) {         
    PageHelper.startPage(dto.getPageNum(), dto.getPageSize()); 
    
    // 设置查询条件    
    Model model = PageQueryReqDTO.convert(dto);
    List<Model> modelList = xxMapper.queryListByCondition(model);
    
    // PageInfo是个泛型,在 new PageInfo<>(modelList)的时候可以把页码、页大小、总页数等信息给pageinfo    
    PageInfo<Model> modelPageInfo = new PageInfo(modelList);
    PageInfo<RespDTO> respPageInfo = new PageInfo<>();
    
    // 将查到的数据复制到返参中    
    List<RespDTO> resultList = new ArrayList<>();    
    if (CollectionUtils.isNotEmpty(modelList)) {        
        modelList.stream().forEach(model -> {            
            RespDTO respDto = new RespDTO();            
            BeanUtils.copyProperties(model, respDto);            
            resultList.add(respDto);       
        });    
    }
    
    // 复制分页属性    
    BeanUtils.copyProperties(modelPageInfo, respPageInfo);    
    target.setList(resultList);        
    
    return respPageInfo;
}

第二种情况更优雅的实现方式

对于第一种情况没什么好说的,针对第二种情况,其实有更优雅的实现方法:

  • 自定义一个 BasePageResponse,即简化版的 PageInfo
  • 将参数传值的逻辑封装到POJO中,Service只做逻辑
  1. 自定义一个 BasePageResponse
@Data
public class BasePageResponse<T> {
    /**
     * 当前页
     */
    private int pageNum;

    /**
     * 每页的数量
     */
    private int pageSize;

    /**
     * 总记录数
     */
    private long total;

    /**
     * 当前页的数量
     */
    private int size;

    /**
     * 总页数
     */
    private int pages;

    /**
     * 是否有下一页
     */
    private boolean hasNextPage = false;

    /**
     * 分页数据
     */
    private List<T> list;

    public static <T> BasePageResponse<T> convert(PageInfo<?> pageInfo) {
        BasePageResponse<T> pageResponse = new BasePageResponse<>();
        pageResponse.setPageNum(pageInfo.getPageNum());
        pageResponse.setPageSize(pageInfo.getPageSize());
        pageResponse.setTotal(pageInfo.getTotal());
        pageResponse.setSize(pageInfo.getSize());
        pageResponse.setPages(pageInfo.getPages());
        pageResponse.setHasNextPage(pageInfo.isHasNextPage());
        return pageResponse;
    }

    public static <T> BasePageResponse<T> convert(BasePageResponse<?> pageInfo) {
        BasePageResponse<T> pageResponse = new BasePageResponse<>();
        pageResponse.setPageNum(pageInfo.getPageNum());
        pageResponse.setPageSize(pageInfo.getPageSize());
        pageResponse.setTotal(pageInfo.getTotal());
        pageResponse.setSize(pageInfo.getSize());
        pageResponse.setPages(pageInfo.getPages());
        pageResponse.setHasNextPage(pageInfo.isHasNextPage());
        return pageResponse;
    }
}

可以发现,就是一个简易版的PageInfo,通过自定义一个 BasePageResponse,可以将页面参数赋值的逻辑封装到BasePageResponse中。

比如现在要查一个User表的信息,但是并不需要全部信息,各类信息如下:

  • UserInfo:user表的model
  • UserQueryPageReqDTO:请参
  • UserQueryPageRespDTO:返参

UserInfo

@Data
class UserInfo {
    private Long id;
    private String name;
    private String age;
    private String address;  // 地址信息不想暴露
}
  1. 将参数转换的逻辑封装到UserQueryPageRespDTO中

UserQueryPageRespDTO

@Builder
@Data
class UserQueryPageRespDTO {
    private Long id;
    private String name;
    private String age;
    // 由于地址信息不想暴露,故在返参中没有给出地址信息
    
    public static BasePageResponse<UserQueryPageRespDTO> convert(PageInfo<UserInfo> pageInfo) {
        BasePageResponse<UserQueryPageRespDTO> pageResponse = BasePageResponse.convert(pageInfo);
        pageResponse.setList(convert(pageInfo.getList()));
        return pageResponse;
    }
    
    private static List<UserQueryPageRespDTO> convert(List<UserInfo> infoList) {
        if (CollectionUtils.isEmpty(infoList)) {
            return Collections.emptyList();
        }

        return infoList.stream().map(UserQueryPageRespDTO::convert).collect(Collectors.toList());
    }
    
    /**
     * 参数赋值
     * 
     * 关于BeanUtils.copyProperties():
     * 当RespDTO参数是Model的子集时,比较适合BeanUtils.copyProperties()去传递两者的属性值,比如上述情况
     * 但是有时候我们的返参中往往会对Model的参数进行一些处理,这时候就不适合用BeanUtils.copyProperties()
     * 而且,不采用BeanUtils.copyProperties()的方式可以看到赋值的过程,也有利于后期维护
     */
    public static UserQueryPageRespDTO convert(UserInfo userInfo) {
        return UserQueryPageRespDTO.builder()
            .id(userInfo.getId())
            .name(userInfo.getName())
            .age(userInfo.getAge)
            .build();
    }
    
}
  1. Service层

由于我们将一些参数转换的逻辑都封装到了POJO中,这样使得Service层很简洁

public BasePageResponse<UserQueryPageRespDTO> userQueryPage(UserQueryPageReqDTO dto) {
    PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
    
    List<UserInfo> list = userInfoMapper.queryPageByCondition(dto);
    PageInfo<UserInfo> pageInfo = new PageInfo<>(list);
    
    return UserQueryPageRespDTO.convert(pageInfo);
}

远程调用时的分页查询

另外注意:

当远程调用时,应该将PageHelper.startPage(dto.getPageNum(), dto.getPageSize());写在被调用服务的一端,因为PageHelper方法使用了静态的ThreadLocal参数,分页参数和线程是绑定的。如果把PageHelper.startPage(dto.getPageNum(), dto.getPageSize());写在调用端,分页信息无法传达到被调用端,也就无法分页,查出来的是全部的条数。

详情看原理篇:PageHelper 分页查询「原理篇」

网站文章

  • 洛谷题目目录 热门推荐

    #1 新手村 关卡1-1 洛谷的第一个任务 超级玛丽游戏(洛谷-P1000):点击这里 A+B Problem(洛谷-P1001):点击这里 小玉买文具(洛谷-P1421):点击这里 小鱼的游泳时间(...

    2024-01-30 23:19:28
  • mysql数据丢失_MySQL是如何保证数据的完整性

    mysql数据丢失_MySQL是如何保证数据的完整性

    本文内容主要介绍了MySQL是如何保证数据的完整性,帮助大家更好的理解和学习MySQL,感兴趣的朋友可以了解下!!!数据的一致性和完整性对于在线业务的重要性不言而喻,如何保证数据不丢呢?今天我们就探讨下关于数据的完整性和强一致性,MySQL做了哪些改进。一. MySQL的二阶段提交 在Oracle和MySQL这种关系型数据库中,讲究日志先行策略(Write-Ahead Logging),只要...

    2024-01-30 23:19:20
  • python软件下载安装百度网盘-python网盘下载

    python软件下载安装百度网盘-python网盘下载

    广告关闭2017年12月,云+社区对外发布,从最开始的技术博客到现在拥有多个社区产品。未来,我们一起乘风破浪,创造无限可能。pip install tencentcloud-sdk-python 注意...

    2024-01-30 23:18:50
  • php.ini开启jd库,.user.ini

    .user.ini究竟是个神秘东东?我们看看官方怎么说:http://php.net/manual/zh/configuration.file.per-user.php自 PHP 5.3.0 起,PH...

    2024-01-30 23:18:43
  • git@github.com: Permission denied (publickey) 热门推荐

    git@github.com: Permission denied (publickey) 热门推荐

    今天在使用命令ssh -T git@github.com测试公钥是否添加成功时,提示:git@github.com: Permission denied (publickey)解决方法方法一:使用默认名字 重新生成密钥对,不指定名字,使用默认名字方法二:使用ssh-agent代理管理git私钥 如果使用的是自己定义的名字 添加本地私钥:ssh-add ~/.ssh/自己定义的名字...

    2024-01-30 23:18:37
  • A08电动汽车BMS功能说明书_11_19

    A08电动汽车BMS功能说明书1、单体电压充电达到4.2V或者总电压达433V后,停止充电,SOC校准为100%2、单体电压放电达到3.2V后,SOC校准为20%46KWH:(1)最低单体小于3.3V...

    2024-01-30 23:18:08
  • JDK1.8 新特性之时间相关

    一、参考文章​​​​​​​​​十分详细的jdk8时间相关操作以及知识点(文章很长)LocalDateTime工具类:根据当前、周、月、季度、半年、年等维度获取时间二、常用 /** * <p>获...

    2024-01-30 23:18:02
  • axure下拉选项和动态面板交互联动:根据不同选项显示对应颜色

    axure下拉选项和动态面板交互联动:根据不同选项显示对应颜色

    因不方便传视频,暂时上传截图效果:上面是下拉框,下面是一个动态面板。会根据下拉框选中的选项,显示对应的颜色。具体的联动过程如下。第一步:在axure页面加一个下拉框,命名为optionList,并增加...

    2024-01-30 23:17:55
  • ueditor清除多余空行

    ueditor清除多余空行

    问题描述 使用ueditor编辑器导入内容的时候,尤其是从第三方网站抓取的内容,往往会存在很多空行 一般的形式是 产生的效果就是会空出一行或者多行,在手机端会显示很多空余的地方 ...

    2024-01-30 23:17:48
  • 性能测试怎么入门?一文7个知识点带你成功入门!

    性能测试怎么入门?一文7个知识点带你成功入门!

    企业中性能测试,一般,先做负载测试,得到最大可接受的并发用户数,再通过这个最 大可接受的并发用户数,进行性能测试,得到性能测试指标值,再根据这个指标值,判断是否符合预期,符合,则测试结束,如果不符合,则需要进行问题定位、分析与调优。一般最后再做压力测试,来测试服务器的稳定性。

    2024-01-30 23:17:19