我开始也想了很久,看了问答区的很多回答,觉得都没有讲到点子上,后面自己翻看了一下这个插件的源码才搞懂的。
首先,我们要知道:
1 | List<Product> productList = productMapper.selectList();
|
这一句当中,productList的实际类型是什么?
我查了一下官方的文档,是这样解释的:
//分页时,实际返回的结果list类型是Page<E>,如果想取出分页信息,需要强制转换为Page<E>,//或者使用PageInfo类
也就是说,productList实际上指向的是一个Page对象。而我们自己写的productListVo仅仅是一个简单的List对象。
那么,为什么我们在这一句中,一定要传入一个Page对象呢?
我们翻看一下new PageInfo(productList);中的构造方法是怎样工作的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | public PageInfo(List<T> list, int navigatePages) {
if (list instanceof Page) {
Page page = (Page) list;
this .pageNum = page.getPageNum();
this .pageSize = page.getPageSize();
this .orderBy = page.getOrderBy();
this .pages = page.getPages();
this .list = page;
this .size = page.size();
this .total = page.getTotal();
if ( this .size == 0 ) {
this .startRow = 0 ;
this .endRow = 0 ;
} else {
this .startRow = page.getStartRow() + 1 ;
this .endRow = this .startRow - 1 + this .size;
}
} else if (list instanceof Collection) {
this .pageNum = 1 ;
this .pageSize = list.size();
this .pages = 1 ;
this .list = list;
this .size = list.size();
this .total = list.size();
this .startRow = 0 ;
this .endRow = list.size() > 0 ? list.size() - 1 : 0 ;
}
if (list instanceof Collection) {
this .navigatePages = navigatePages;
calcNavigatepageNums();
calcPage();
judgePageBoudary();
}
}
|
我们发现,如果传进来的是一个Page对象,将会根据这个Page对象计算相应的数值,此时Page对象的total为数据库中实际数据的总条数,而不是我们查出来的List的大小。包括当前实际处于的页数pageNum也是准确的。代码如下所示:
1 2 | this .total = page.getTotal();
this .pageNum = page.getPageNum();
|
但是,我们仍然会发现,如果传入的参数不是Page对象,而是直接传入一个List的话,又是怎么处理的呢?我们发现,处理过程非常简单粗暴:
1 2 3 4 5 6 7 8 9 10 | else if (list instanceof Collection) {
this .pageNum = 1 ;
this .pageSize = list.size();
this .pages = 1 ;
this .list = list;
this .size = list.size();
this .total = list.size();
this .startRow = 0 ;
this .endRow = list.size() > 0 ? list.size() - 1 : 0 ;
}
|
此时,直接把当前页数设置为第1页(实际可能不是第1页),总数total设置为List的大小,然而我们数据库中的数据肯定不止这个List这么大,因此,此时计算出来的页面信息全是错误的!
1 | List<Product> productList = productMapper.selectList();
|
因此,如果我们先传入Mapper返回来的这个productList(实际上也是一个Page对象),那么我们在执行
1 | PageInfo pageResult = new PageInfo(productList);
|
的时候,算出来的什么pageNum啊,total啊都是实际数据库中的数值,而不是简单的1和List的大小。
但是,我们最后又需要传给前端produstListVoList,因此,我们在构造函数算完这些值后,然后在替换其中的productList为productListVoList,前端既能收到productListVoList,又能得到正确的页面信息。
所以,老师第一步传入productList只是借来算页面信息的,实际展示给前端的还是展示productListVoList对象。
希望能帮助到一些同学,有错误欢迎指出。
更多详细内容,欢迎参考我的博客:https://blog.csdn.net/qq_19782019