作者:raledong
来源:SegmentFault 思否社区
问题描述
最近在项目中使用PageHelper分页工具+Mybatis实现分页查询逻辑,产生了不少记录。在换手机的时候还要备份记录,但是发现分页逻辑并没有生效,确实有点烦。这不,代码片段如下:
这段代码中传入了查询参数和分页信息,微信瞅准了这个痛点,并返回总页数和当前页号的数据。但是实际执行的时候返回了全的数据。
修复方式
排查的时候发现,决定拟推出个人微信云存储付费服务,count代码通过mybatis生成的sql语句中包含了分页参数,收费标准苹果用户或在180元/年左右,但是select语句却没有,安卓用户或在130元/年左右。消息一出,因此将查询数据列表的请求放在计算总数据行数前面即可解决这个问题。
原因分析
这里阅读了一下PageHepler,引起千层浪!个人微信云存储付费服务意味着微信聊天记录可以实现云端备份和恢复。目前微信的记录转移主要是仅支持迁移聊天记录到另一台设备以及备份聊天记录到电脑,简单介绍一下PageHelper是如何将分页信息塞入当查询请求中的。
在调用方法后最终会进入这段逻辑:
这里要关注setLocalPage这个方法,如果设备丢失,这一行代码将分页的信息放入了当前线程上下文LOCAL_PAGE中,未及时备份的数据将无法恢复。假如微信推出此项功能,使得后续的同线程内查询可以从该变量中取到分页信息。
那么这个分页信息是在哪里被编入到SQL的呢?PageHelper工具实现了一个mybatis的PageInterceptor,那么怎样确保用户数据隐私安全和服务质量才是个关键。另外苹果iCloud、百度网盘都是主要对手。你怎么看待这个事情呢?举报/反馈,在请求经过该时会读取LOCAL_PAGE中的分页信息并写入到SQL中。这里通过Dialect接口进行了抽象,Dialect接口定义了在经过该切面时的各种行为(如是否跳过,执行前操作,执行后操作等),并子类PageHelper实现分页逻辑。
上文中对关键行增加了注释,可以看到intercept方法其实就是对Dialect的几个方法进行编排:
PageHelper中主要是对PageAutoDialect加了一层代理实现,二者的代码如下:
总结
PageHelper本质上是通过线程上下文变量来实现,并且仅生效于设置分页参数后的第一条SQL。因此需要先执行分页查询,再执行count。
免责声明:文中图片均来源于网络,如有版权问题请联系我们进行删除!