大家好,我叫大鸡腿,大家可以关注下我,会持续更新技术文章还有人生感悟,感谢~
功能介绍
PageHelper跟Mybatis结合实现分页功能
基础使用方法
PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
原理
mybatis在执行sql的时候通过代理Proxy,拦截器Interceptor,从PageHelper获取ThreadLocal或者Page对象的参数重新编写sql。执行完返回数据
一般到这里会很奇怪,为啥到这里就没有接下来了呢?就赋值了一个本地变量?
其实最重要的是拦截器在起作用,可以参考下链接: mybatis自定义拦截sql并修改参数.
源码
DEBUG模式:在执行sql之后会到代理
最重要
拦截器,当执行sql之后会运行intercept方法
/**
* 获取分页参数
*
* @param <T>
* @return
*/
public <T> Page<T> getLocalPage() {
return PageHelper.getLocalPage();
}
这里会去获取PageHelper里面的ThreadLocal Page分页参数:每页数量,页码
存在的坑
举个栗子
List<ContentPrivateLetterV2Vo> list = contentPrivateLetterMapper.selectSystemLetter(dto);
if (CollectionUtils.isEmpty(list)) {
return new PageInfo<>();
}
List<ContentPrivateLetterV1Vo> newList = BeanUtils.convertList(list, ContentPrivateLetterV1Vo.class);
list是我们查出来的队列,我们对它进行相关的属性映射,或者等等操作。如果这个时候我们直接这样返回PageInfo pageInfo = new PageInfo<>(newList);的话,会变成total总数只有10.
为啥?
看下total的设置:debug模式进入see see
有些表面是List,其实它类型是Page类型,获取Page的total数量,而不是List数量
如果你进行相应的操作转换成List之后,它的total数量就是List的大小了。
工具类
so我们有个工具类是这样的:
public static <T> PageInfo<T> buildPageInfo(List<?> sourList, List<T> targetList) {
PageInfo<T> pageInfo = new PageInfo<>();
if (sourList instanceof Page) {
Page<?> page = (Page<?>) sourList;
pageInfo.setTotal(page.getTotal());
pageInfo.setPageNum(page.getPageNum());
pageInfo.setPageSize(page.getPageSize());
}
pageInfo.setList(targetList);
return pageInfo;
}
转前的List其实是Page类型,后面是操作sourList之后生成的targetList。
总结
PageHelper通过拦截器对sql进行相应的改造,然后是远程调用接口是分页不了的,因为没有经过查询数据库。而且分页只对第一条查询sql语句起作用哦~,不要对查询出来的List进行相关的操作,不然也会出现bug