背景
我们的springboot应用程序的持久层 ,是用jeecgboot框架生成的代码 。mybatisplus版本是3.1.2 。
在一次对当前程序的sql性能优化时 ,我重写了BaseMapper的selectPage方法。其中,为Wrapper<T>参数加上了id限制 ,以提高sql执行性能 。
问题描述
程序上线后运行了一段时间 。后来 ,发现了一个问题 。见下面日志截图
原来呢 ,service类里调用这个分页的方法里 ,并不是每次调用分页时都new一个Wrapper对象 ,而是重复使用一个Wrapper对象 。 所以 ,出现上图的问题就不难理解了 。
解决办法 -Wrapper#getCustomSqlSegment
头疼医头的方式 ,是修改service类里调用这个分页的方法 ,每次调用分页前都new一个Wrapper对象 。
显然 ,这样解决问题只是一时 。以后再有调用这个分页的地方,依然会存在这个问题呀 。
所以 ,我的解决办法是利用 Wrapper#getCustomSqlSegment , 上面sql里重复出现的是 id BETWEEN 。所以,修正的代码如下:
// 外面调用处可能复用这个queryWrapper对象。所以 ,为避免重复追加条件 ,这里先做判读再追加 。
if (!queryWrapper.getCustomSqlSegment().contains("id BETWEEN")) {
if (queryWrapper instanceof LambdaQueryWrapper) {
((LambdaQueryWrapper<SbhPlatOrder>) queryWrapper).between(SbhPlatOrder::getId, prePageDto.getMinId(), prePageDto.getMaxId());
} else if (queryWrapper instanceof QueryWrapper) {
((QueryWrapper<SbhPlatOrder>) queryWrapper).lambda().between(SbhPlatOrder::getId, prePageDto.getMinId(), prePageDto.getMaxId());
}
}
更好的解决办法-Wrapper#clone
利用clone方法 。mybatisplus的Wrapper的抽象父类AbstractWrapper,重写了超类Object的clone方法。如下是源码:
package com.baomidou.mybatisplus.core.conditions;
public abstract class AbstractWrapper ...{
@Override
@SuppressWarnings("all")
public Children clone() {
return SerializationUtils.clone(typedThis);
}
}
相比上面的解决办法 ,我认为这是更好的解决办法 ,这样修正的代码如下:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface SbhPlatOrderMapper extends BaseMapper<SbhPlatOrder> {
@Override
default IPage<SbhPlatOrder> selectPage(IPage<SbhPlatOrder> page, @Param(Constants.WRAPPER) Wrapper<SbhPlatOrder> queryWrapper){
Wrapper<SbhPlatOrder> queryWrapperClone = queryWrapper.clone();
PrePageDto prePageDto = selectCountCache(queryWrapperClone);
page.setTotal(prePageDto.getRowCount());
if (prePageDto.getRowCount()>0) {
if (queryWrapperClone instanceof LambdaqueryWrapperClone) {
((LambdaQueryWrapper<SbhPlatOrder>) queryWrapperClone).between(SbhPlatOrder::getId, prePageDto.getMinId(), prePageDto.getMaxId());
} else if (queryWrapperClone instanceof QueryWrapper) {
((QueryWrapper<SbhPlatOrder>) queryWrapperClone).lambda().between(SbhPlatOrder::getId, prePageDto.getMinId(), prePageDto.getMaxId());
}
page.setRecords(selectPageList((page.getCurrent() - 1) * page.getSize(), page.getSize(), queryWrapperClone));
}
return page;
}
。 。。
}
EOF-thanks!
声明:本站所有文章 ,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织 ,在未征得本站同意时 ,禁止复制 、盗用 、采集、发布本站内容到任何网站 、书籍等各类媒体平台 。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。