当前位置:首页 > 数码 > 原来PageHelper还有这个坑! (原来神马在线观看免费完整版)

原来PageHelper还有这个坑! (原来神马在线观看免费完整版)

admin5个月前 (04-30)数码25

插件PageHelper很多人都会经常使用吧,有一次性Copy的时刻忘了去掉PageHelper.startPaeg()方法,结果造成数据查不到,debug的时刻发现第一次性查问没有数据,再查问一次性就有数据了,这个坑居然也花了一点期间,那么当天就把这个坑填平。

这里咱们一同看看其原理以及日经常常使用留意事项。

如何经常使用PageHelper

PageHelper是Mybatis-Plus中的一个插件,关键用于成功数据库的分页查问性能。其外围原理是将传入的页码和条数赋值给一个Page对象,并保管到本地线程ThreadLocal中。接上去,PageHelper会进入Mybatis的阻拦器环节,在阻拦器中失掉并处置刚才保管在ThreadLocal中的分页参数。这些分页参数会与原本的SQL语句和外部曾经定义好的SQL启动拼接,从而成功带有分页处置的SQL语句的构建。

Pagehelper有很多种经常使用方式,上方列出官网给出的几种经常使用方式。

//第一种,RowBounds方式的调用List<Country>list=sqlSession.selectList("x.y.selectIf",null,newRowBounds(0,10));//第二种,Mer接口方式的调用,介绍这种经常使用方式。PageHelper.startPage(1,10);List<Country>list=countryMapper.selectIf(1);//第三种,Mapper接口方式的调用,介绍这种经常使用方式。PageHelper.offsetPage(1,10);List<Country>list=countryMapper.selectIf(1);//第四种,参数方法调用//存在以下Mapper接口方法,你不须要在xml处置后两个参数publicinterfaceCountryMapper{List<Country>selectByPageNumSize(@Param("user")Useruser,@Param("pageNum")intpageNum,@Param("pageSize")intpageSize);}//性能supportMethodsArguments=true//在代码中间接调用:List<Country>list=countryMapper.selectByPageNumSize(user,1,10);//第五种,参数对象//假设pageNum和pageSize存在于User对象中,只需参数有值,也会被分页//有如下User对象publicclassUser{//其余fields//上方两个参数名和params性能的名字分歧privateIntegerpageNum;privateIntegerpageSize;}//存在以下Mapper接口方法,你不须要在xml处置后两个参数publicinterfaceCountryMapper{List<Country>selectByPageNumSize(Useruser);}//当user中的pageNum!=null&&pageSize!=null时,会智能分页List<Country>list=countryMapper.selectByPageNumSize(user);//第六种,ISelect接口方式//jdk6,7用法,创立接口Page<Country>page=PageHelper.startPage(1,10).doSelectPage(newISelect(){@OverridepublicvoiddoSelect(){countryMapper.selectGroupBy();}});//jdk8lambda用法Page<Country>page=PageHelper.startPage(1,10).doSelectPage(()->countryMapper.selectGroupBy());//也可以间接前往PageInfo,留意doSelectPageInfo方法和doSelectPagepageInfo=PageHelper.startPage(1,10).doSelectPageInfo(newISelect(){@OverridepublicvoiddoSelect(){countryMapper.selectGroupBy();}});//对应的lambda用法pageInfo=PageHelper.startPage(1,10).doSelectPageInfo(()->countryMapper.selectGroupBy());//count查问,前往一个查问语句的count数longtotal=PageHelper.count(newISelect(){@OverridepublicvoiddoSelect(){countryMapper.selectLike(country);}});//lambdatotal=PageHelper.count(()->countryMapper.selectLike(country));

PageHelper原理

其外围原理是将传入的页码和条数赋值给一个Page对象,并保管到本地线程ThreadLocal中。

上方以经常出现的经常使用方式看一下:

PageHelper.startPage(1,10,orderBy);
PageHelper

经过一些列的循环俄罗斯套娃调用之后,到来了这里:

publicstatic<E>Page<E>startPage(intpageNum,intpageSize,booleancount,Booleanreasonable,BooleanpageSizeZero){Page<E>page=newPage<E>(pageNum,pageSize,count);page.setReasonable(reasonable);page.setPageSizeZero(pageSizeZero);//当曾经口头过orderBy的时刻Page<E>oldPage=getLocalPage();if(oldPage!=null&&oldPage.isOrderByOnly()){page.setOrderBy(oldPage.getOrderBy());}setLocalPage(page);returnpage;}

图片

PageHelper中有写了一个com..pagehelper.PageInterceptor,这里是口头分页的中央。假设你想要写其余的阻拦器,也可以自定义一个mybatisplugin包阻拦器,在这里对sql启动处置。

图片

图片

图片

图片

图片

PageHelper在口头这一环节时,会判别SQL的类型,只要当该SQL是查问操作时,才会进入分页逻辑。并且,在进入分页逻辑处置后,PageHelper会经过反射失掉该方法的参数,判别能否存在IPage对象(这是Mybatis-Plus中的另一个分页对象)的成功类。假设存在这样的成功类,那么也会启动相应的分页处置。

PageHelper留意事项

经常使用PageHelper分页介绍经常使用PageHelper.startPage(1,10)这种方式。

另外startPage语句最好紧挨着查问语句,防止两边抛出意外,没有方法肃清ThreadLocal中以后线程的page对象。

上方看一下官网给出的不安保的用法和介绍的例子:

不安保用法:上方的方法假设不走查问的话,page对象就会保管在以后线程中,算是一个内存走漏,假设下一个mybatis查问方法刚好是这个线程的时刻,就会主动分页。

PageHelper.startPage(1,10);List<Country>list;if(param1!=null){list=countryMapper.selectIf(param1);}else{list=newArrayList<Country>();}

介绍用法,关键是紧挨着mybatis查问方法,查问完结后,page对象就被清算,对线程后续的运转不受影响。

List<Country>list;if(param1!=null){PageHelper.startPage(1,10);list=countryMapper.selectIf(param1);}else{list=newArrayList<Country>();}

回到最开局的那个坑,要素就在于失误的经常使用了PageHelper.startPage(page,size),这里的分页参数只是调用下游系统的分页参数,不应该再这里经常使用,所以在第一页的时刻是没疑问的,到第二页的时刻,查问就出疑问了,数据库中没有那么少数据,所以会查不到数据。debug的时刻,口头一次性数据查问操作,把page对象消耗掉了,第二次查问的数据没有分页参数,所以就可以反常查问出数据。


PageHelper失效踩坑

常见的pageHelper失效,一般由编写失误导致,根据源码指出()方法必须放在查询的上面, 并且分页只会对下面第一次查询有效 我们这次的失效不是编写失误造成,从位置到mybatis映射都review了好几遍,没有发现任何失误 他的作用指,如果db总条数也就是total,小于了pageNum*pageSize之后的条数,那么他就会重定向pageNum为合理的数值, 案例中pageNum就被重新指定回了1,所以还能查出来 一般前端同学来说,不会发现这个问题,因为前端分页组件一般都会根据total除以pageSize来加载一共多少页,不会出现pageNum不合理的情况,但对于后端对接后端同学来说,如果对方工作做的疏忽传了个不合理的值,那么就会出现这个情况,总之我们可以注释掉这段配置即可

怎么把参数传递pagehelper.startpage

因为分页查询结果返回的是一个 Page 对象,而 Page 对象继承自ArrayList,但是如果我们直接返回ArrayList的话,在一些场景下回遇到问题,比如在JSON处理Page类型的结果时,会被当成List来JSON格式化,会丢弃 Page 对象的所有扩展属性,所以这里我们要将分页的结果 Page 类型转换成我们自己定义的 PageBean. 我们自己定义的PageBean没有继承ArrayList,而是包含一个List属性来保存分页结果。 所以避免前面的问题。 2)修改 serviceImpl中的代码: @Overridepublic PageBean<User> getUserByNoAndEmail(String no, String email) {Map<String, Object> map = new HashMap<>();(no, no);(email, email);((), ());List<User> list = (map);return new PageBean<User>(list);}我们只需要使用 (pageNum, pageSize); 函数来指定 pageNum(第几页) 和 pageSize(每页显示几条记录) 两个参数。 然后调用原来的查询,就进行了分页。 最后将返回的List,转换成 PageBean类型的结果即可。 前台页面就可以根据PageBean中包括的属性来进行分页显示了。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: PageHelper