在使用人人开源框架的时候,通过逆向工程自动生成了分页功能,然而在使用的时候经常被关于Ipage和page等对象搞混,所以记录这篇文章用来介绍之间的区别
@Override
public PageUtils queryPage(Map<String, Object> params) {
IPage<OrderFormEntity> page = this.page(
new Query<OrderFormEntity>().getPage(params),
new QueryWrapper<OrderFormEntity>()
);
return new PageUtils(page);
}
可以看见上面就是逆向工程帮忙生成的分页方法
里面出现了三个对象pageUtils、page和Ipage
先来将pageUtils吧,pageUtils是人人代码自己存在的一个功能类,用来包装Ipage
public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
this.list = list;
this.totalCount = totalCount;
this.pageSize = pageSize;
this.currPage = currPage;
this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
}
/**
* 分页
*/
public PageUtils(IPage<?> page) {
this.list = page.getRecords();
this.totalCount = (int)page.getTotal();
this.pageSize = (int)page.getSize();
this.currPage = (int)page.getCurrent();
this.totalPage = (int)page.getPages();
}
目的很简单就是为包装Ipage类,方便后端的调用,下图是后端如何调用pageUtil(其实不用包装也能直接使用Ipage)
if (data && data.code === 0) {
this.dataList = data.page.list;
this.totalPage = data.page.totalCount;
} else {
this.dataList = [];
this.totalPage = 0;
}
this.dataListLoading = false;
});
接下来再来看Ipage的生成,Ipage的生成调用了mybatis-plus自带的方法this.getPage,方法传入两个参数,一个是page类,一个是qw,通过这个方法,用户可以自定义自己想要的分页数据,简单来说就是在page上再筛选而后得到Ipage。
那么Ipage是怎么生成的呢,很简单创建一个Query对象,通过对象内部的getPage方法,传入参数params获得分页数据
那么Page是怎么生成的呢
public IPage<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc) {
//分页参数
long curPage = 1;
long limit = 10;
if(params.get(Constant.PAGE) != null){
curPage = Long.parseLong((String)params.get(Constant.PAGE));
}
if(params.get(Constant.LIMIT) != null){
limit = Long.parseLong((String)params.get(Constant.LIMIT));
}
//分页对象
Page<T> page = new Page<>(curPage, limit);
//分页参数
params.put(Constant.PAGE, page);
//排序字段
//防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险)
String orderField = SQLFilter.sqlInject((String)params.get(Constant.ORDER_FIELD));
String order = (String)params.get(Constant.ORDER);
//前端字段排序
if(StringUtils.isNotEmpty(orderField) && StringUtils.isNotEmpty(order)){
if(Constant.ASC.equalsIgnoreCase(order)) {
return page.addOrder(OrderItem.asc(orderField));
}else {
return page.addOrder(OrderItem.desc(orderField));
}
}
//没有排序字段,则不排序
if(StringUtils.isBlank(defaultOrderField)){
return page;
}
//默认排序
if(isAsc) {
page.addOrder(OrderItem.asc(defaultOrderField));
}else {
page.addOrder(OrderItem.desc(defaultOrderField));
}
return page;
}
}
传入的params并不会做任何的筛选只会做分页的基本初始化,例如两个参数contant.Page 和constant.LIMIT,如果不做任何要求,那么getPage会使用自己默认的当前页和页最大数,然后创建page对象,在page对象添加排序规则,最后把这个初始好的对象返回回去。
最后this.page再调用底层的selectPage
default <E extends IPage<T>> E page(E page, Wrapper<T> queryWrapper) {
return this.getBaseMapper().selectPage(page, queryWrapper);
}
其实mybatis-plus提供最基本的分页查询就是使用selectPage方法
总结:代码生成器生成的分页查询操作,是通过层层包装selectPage方法,最终获得queryPage,而Ipage是page的包装,pageUtils是Ipage的包装