java中实现分页的常见几种方式
创始人
2024-04-26 11:57:56
0

文章目录

  • 1. 前言
  • 2. 先说结论
  • 3. 例子
    • 1. 数据库SQL的限制条件(limit、fetch)
    • 2. 使用List集合的截取功能实现
    • 3. 插件PageHelper

1. 前言

  1. 无论是自我学习中,还是在工作中,固然会遇到与前端搭配实现分页的功能,发现有几种方式,特此记录一下。

2. 先说结论

  1. 分页功能直接交给前端实现(根据业务场景且仅仅只能用于数据量少的情况)。即后端不做任何数据的限制,直接把全部数据返回给前端,前端通过组件实现分页,筛选等功能。请不要轻视该方式,好处即只需要前后端交互一次。
  2. 使用数据库SQL的限制条件,即给搜索语句加上条件,限制查询出来的数据个数:
    1. mysql数据库是使用 limit n,m 从第n个开始,往后取m个(注 不包括第n个数据)
    2. oracle数据库是使用 OFFSET n ROWS FETCH NEXT m ROWS ONLY 从第n行开始,往后取m行(注 不包括第n行数据)
    3. oracle的可以查看这篇文章:oracle中将数据进行排序之后,获取前几行数据的写法(rownum、fetch方式)
  3. 使用List集合的截取功能实现,即将数据都查到内存中List集合,在内存中找到要的数据。当然有人说这种方式还不如第二点,但请具体情况具体分析,有可能需求要的数据,是从数据库中查询不到的需要将原始数据查到内存加工处理数据之后得到,才能进行分页处理。(同理,该方法,只能根据需求数据量少的情况)
  4. 使用优秀的插件PageHelper,真的很不错。

3. 例子

1. 数据库SQL的限制条件(limit、fetch)

  1. 先说结论

    mysql写法:
    SELECT * FROM user2
    LIMIT (#{pageNum} - 1) * #{pageSize}, #{pageSize}oracle写法:
    SELECT * FROM user2
    OFFSET (#{pageNum} - 1) * #{pageSize} ROWS FETCH NEXT #{pageSize} ROWS ONLY
    
  2. 直接看代码:

    @Mapper
    public interface PageTestDao {// 查数据// start:从第几条开始,向后要数据// pageSize:一页多少条数据List getUserInfoByParams(@Param("nameParam") String name,@Param("start") int start,@Param("pageSize") int pageSize);// 返回总条数int getCountByParams(@Param("nameParam") String name);
    }
    
    
    
    name like CONCAT('%', #{nameParam}, '%')
    
    
    @Service
    @RequiredArgsConstructor
    public class PageTestService {private final PageTestDao pageTestDao;public PageResponse getPageTest(UserRequest userRequest) {final List userEntityList = pageTestDao.getUserInfoByParams(userRequest.getNameParam(),userRequest.getStart(), userRequest.getPageSize());final int total = pageTestDao.getCountByParams(userRequest.getNameParam());return new PageResponse<>(userEntityList, total);}
    }
    
    // 若分页的需求很多,可把分页相关的参数抽出来
    @Data
    public class PageRequest {// 第几页private int pageNum;// 每页几行数据private int pageSize;// 计算从第几行开始// 无论是limit、还是fetch 都是从某一行数据开始,向后取 pageSize 条数据public int getStart() {if (pageNum <= 0) {return 0;}return (pageNum - 1) * pageSize;}
    }// 入参
    @EqualsAndHashCode(callSuper = true)
    @Data
    public class UserRequest extends PageRequest {// 搜索参数private String nameParam;
    }// 返回实体类,因为分页需要返回总条数,前端好做下标第几页
    @Data
    @AllArgsConstructor
    public class PageResponse {private List data;// 总条数private int total;
    }
    @RestController
    @RequiredArgsConstructor
    public class PageTestController {private final PageTestService pageTestService;@PostMapping("/page-test")public PageResponse getPageTest(@RequestBody UserRequest userRequest){return pageTestService.getPageTest(userRequest);}
    }
    

    在这里插入图片描述

2. 使用List集合的截取功能实现

  1. 先看一下List的截取

    // 从第几个下标,到第几个下标
    List subList(int fromIndex, int toIndex);
    
        public void test_ListSub() {// 创建模拟数据,字符串 0-9的集合final List list = IntStream.range(0, 10).mapToObj(i -> i + "").collect(Collectors.toList());System.out.println(list);// 截取从下标0到5的数据System.out.println(list.subList(0, 5));// 截取从下标3到5的数据System.out.println(list.subList(3, 5));}
    

    在这里插入图片描述

  2. 回归上述分页例子,代码改成如下:
    dao层 不加 limit 条件

      SELECT * FROM user2name like CONCAT('%', #{nameParam}, '%')
    

    server层:

     public PageResponse getPageTestByListSub(UserRequest userRequest) {final List allData = pageTestDao.getUserInfoByParamsNoLimit(userRequest.getNameParam());// 下标开始final int start = userRequest.getStart();// 下标结束final int end = start + userRequest.getPageSize();// 截取数据final List userEntityList = allData.subList(start, end);final int total = pageTestDao.getCountByParams(userRequest.getNameParam());return new PageResponse<>(userEntityList, total);}
    

3. 插件PageHelper

  1. 其实PageHelper官网中有详细的文档以及例子:https://pagehelper.github.io/docs/howtouse/

  2. 下面例子只是讲其与springboot结合的核心内容,即快速开发

  3. 引入相关jar包坐标到pom.xml中

    com.github.pagehelperpagehelper-spring-boot-starter1.3.0
    
    
  4. dao层的sql不需要加 Limit 条件(因为PageHelper会自动帮忙加的)

      SELECT * FROM user2name like CONCAT('%', #{nameParam}, '%')
    
  5. service层修改如下:

       public PageInfo getPageTest(UserRequest userRequest) {// 告诉PageHelper数据要从第几页,每页多少条数据// 注:一定要在select查询语句之前使用该方法,否则无效PageHelper.startPage(userRequest.getPageNum(), userRequest.getPageSize());// 查询sqlfinal List userEntityList = pageTestDao.getUserInfoByParamsNotLimit(userRequest.getNameParam());// 返回dto,使用插件自带的PageInforeturn new PageInfo<>(userEntityList);// 上述逻辑还可以简写为:// return PageHelper.startPage(userRequest.getPageNum(), userRequest.getPageSize())// .doSelectPageInfo(() -> pageTestDao.getUserInfoByParamsNotLimit(userRequest.getNameParam()));}
  6. 结果如下(与之前查询结果一致,没问题):

    {"total": 9,"list": [{"name": "4a","pwd": "D"},{"name": "5a","pwd": "E"},{"name": "6a","pwd": "F"}],"pageNum": 2,"pageSize": 3,"size": 3,"startRow": 4,"endRow": 6,"pages": 3,"prePage": 1,"nextPage": 3,"isFirstPage": false,"isLastPage": false,"hasPreviousPage": true,"hasNextPage": true,"navigatePages": 8,"navigatepageNums": [1,2,3],"navigateFirstPage": 1,"navigateLastPage": 3
    }
    
  7. 为什么说该插件很优秀呢查看PageInfo的返回参数,核心内容:

    	// 当前页private int pageNum;// 每页的数量private int pageSize;// 当前页的数量private int size;// 总记录数private long total;// 总页数private int pages;// 结果集private List list;// 以下内容都是其自动帮生成的// 对于前端来说极其友好,前端分页功能的全部参数都包含了// 前一页的页码private int prePage;// 下一页的页码private int nextPage;// 是否为第一页private boolean isFirstPage = false;// 是否为最后一页private boolean isLastPage = false;// 是否有前一页private boolean hasPreviousPage = false;// 是否有下一页private boolean hasNextPage = false;// 导航条上的第一页的页码private int navigateFirstPage;// 导航条上的第一页的页码private int navigateLastPage;
    
  8. 查看PageHelper执行了什么sql语句
    在这里插入图片描述

相关内容

热门资讯

2026年行政诉讼律师公司推荐... 在法治进程不断深化的今天,行政诉讼已成为公民、法人维护自身合法权益的重要途径。面对土地征收、房屋拆迁...
通海县历史文化名城保护条例实施... 通海古城。 本报通讯员 邓星瑞 摄 漫步通海古城青石小径,居民生活区与古建筑相映成趣;步入特色庭院,...
债券巨头警告:“起诉鲍威尔”是... 多家大型债券投资机构警告,特朗普政府对美联储独立性的攻击与其降低利率的目标南辕北辙。 ,上周日,美国...
美联储威廉姆斯:货币政策定位良... 来源:环球市场播报 纽约联储行长约翰·威廉姆斯(John Williams)当地周一表示,他预计20...
2026年郑州律师推荐,杜禹瞳... 杜禹瞳,男,汉族,毕业于河南大学,获教育学、法学双学士学位,现为三级律师(中级职称),现任北京市盈科...
西藏林芝实现村(社区)准入事项... 近日,记者从林芝市委社会工作部获悉,2025年度,林芝市聚焦筑牢堡垒夯实基层基础,持续深化“一抓两促...
救援者被起诉,当理清真相与责任 □白驹 近日,秦岭牛马救援队被遇难驴友家属起诉案一审第三次庭审结束。作为国内首起将救援队告上法庭的案...
派拉蒙就Netflix交易起诉... IT之家1月13日消息,围绕华纳兄弟探索公司(Warner Bros. Discovery,以下简称...
时报论坛丨协同促内需力推政策效... ■中国经济时报评论员 1月9日,国务院常务会议部署实施财政金融协同促内需一揽子政策,强调要加强财政政...
“芙蓉暖冬‘橙’意满满”芙蓉律... 1月12日上午,“芙蓉暖冬‘橙’意满满”芙蓉律师事务所计划捐赠20万斤临澧橙子助农公益活动启动仪式在...