场景是两个项目合并,一个用到了PageHelper
一个用到了MybatisPlus
,然后发现MybatisPlus
查询的Conditon失效了…
分析问题
断点半天发现参数中途被PageHelper
的ExecutorUtil#pageQuery
清空了。具体是在PageInterceptor
中调用的。没有细致看代码功能,字面意思大概是skip
返回false
就会走分页的处理。
if (!this.dialect.skip(ms, parameter, rowBounds)) {
//...
resultList = ExecutorUtil.pageQuery(this.dialect, executor, ms, parameter, rowBounds, resultHandler, boundSql, cacheKey);
} else {
resultList = executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql);
}
那看看dialect
这个变量是哪里来的,在下面可以找到初始化的地方。可以看出这个是可配置的,且有个默认值。默认值是com.github.pagehelper.PageHelper
,且不难发现dialect
这个配置是可以在Spring的配置文件里面配置的:pagehelper.dialect
。
public void setProperties(Properties properties) {
String dialectClass = properties.getProperty("dialect");
if (StringUtil.isEmpty(dialectClass)) {
dialectClass = this.default_dialect_class;
}
//...
//反射创建dialect的代码
}
断点发现,实际上使用的就是默认的default_dialect_class
。
解决问题
那思路应该是自己实现接口去根据什么字段去区分skip的返回值,这里直接直接继承default_dialect_class
。
这里可以根据ms
参数里面某些字段判断是否是哪个框架发起的,具体没有多看是选什么参数比较好,我直接用的id,前面半截是包名。
这样就可以不同的框架,走不同分页逻辑了。
public class PageConflictHelper extends PageHelper {
@Override
public boolean skip(MappedStatemen ms, Object parameterObject, RowBounds rowBounds) {
if(StrUtil.startWith(ms.getId(), "xxx")) {
return super.skip(ms, parameterObject, rowBounds);
}
return true;
}
}
其他
不晓得有没有坑,目前看起来是还行。最好是统一用同一个框架吧,不要打补丁。