springboot项目中离不开分页查询,下面
对常用的两种分页查询方法作一下总结:
前端分页请求调用实现
以下给出后端所对应的2种处理方法:
一、手写分页
首先在后端接收前端所传递过来的pageNum与pageSize,并作以下两个步骤:
1)计算查询偏移量offse = (start - 1) * size ,然后在xml的sql语句中手写limit语句;
2)计算查询数据的总条数total,需要一并返回给前端(这样前端才知道分多少页);
另外为了更加方便,可以构建一个pagemram的分页参数类,然后让实体类继承该分页参数类即可;在PageParam类中便直接计算出偏移量offset,这样mybatis在xml的中获取offset参数值时,会自动调用相关get方法返回参数值。
二、利用mybatis的分页插件(PageHelper)
这里以若依框架中插件分页写法为例:
以上三条语句即可完成分页功能,其中startPage()分页语句必须在查询的前面,且只对一次查询起到分页作用,下面对三条语句逐一进行剖析:
1. startPage()
首先,代码 TableSupport.buildPageRequest(); 是从请求request中获取前端传递的分页参数,具体怎么实现的可以参考这篇文章:若依分页实现-优快云博客https://blog.youkuaiyun.com/BADAO_LIUMANG_QIZHI/article/details/108017635?spm=1001.2014.3001.5506
其次,代码 PageHelper.startPage(pageNum, pageSize)才是真正起到分页作用的。小伙伴们肯定会疑惑,该条语句也没有将任何分页信息传递到第二条查询语句中,那到底是怎么起到作用的呢?
答案就是插件PageHelper用到了ThreadLocal变量存储知识,该变量为同一线程所共享的变量空间。pageHelper调用startPage()方法将从前端所获得的分页数据信息存入线程共享变量ThreadLocal中,这样mybatis在进行数据查询时,便会获取到分页信息。具体原理是Mybatis里面配置了分页拦截器,这样在执行相关Sql之前会拦截并做一些事情,感兴趣的同学可以深入了解一下。
2. 查询数据返回 list
我们知道分页查询需要我们获取到数据的总条数total并返回给前端,从第2条查询代码中并未看到有关总条数的信息啊?这是令人疑惑的。
那么下面我们说回mybatis的分页拦截器拦截所做的一些事情,在这一步骤中主要做了2件事情,在进行list查询时,除了添加上limit(start , size)进行分页数据查询,还进行了一次count(0)的总数据条数查询,这是非常重要的。因此这样我们也获得了数据总条数total,但是我们看到返回的是一个List类型呀,并没有total信息啊? 那么我们通过debug调试便可发现,查询返回的list是Page类型???那么什么是Page类型呢,进入其源代码可以看到:
恍然大悟,原来Page类继承了ArrayList,这样一切就可以说的通了,原来当我们利用mybatis的分页插件(PageHelper)时,所查询返回的list就自动变成了带分页属性的Page类,那么这样在list中就自然带有了total的信息(这里作了向上转型),也可以参考这篇文章的深入解释。PageHelper.startPage的一些探索和思考-优快云博客https://blog.youkuaiyun.com/shijiujiu33/article/details/99477704?spm=1001.2014.3001.5506
3. getDataTable(list) 返回分页信息数据
进入 getDataTable(list)的源代码:
关键一步便是将查询得到的list填入new PageInfo(list)中,对list所携带的分页数据进一步处理