Mybatis-Plus查询大量数据时,慢!

Mybatis-Plus查询大量数据时很慢!

解决:

1.采用 少量多次的方法来处理

        int count= service.count();
        int pageSize=10000;
        int pageNum=(count/pageSize)+1;
        AtomicInteger iStart = new AtomicInteger(0);
        final String limit="limit ";
        Stream<Integer> iterate = Stream.iterate(0, i -> ++i);
        iterate.limit(pageNum).parallel().forEach(integer -> {
            QueryWrapper<Object> objectQueryWrapper = new QueryWrapper<>();
            objectQueryWrapper.last(limit+ iStart.getAndAdd(pageSize) +","+pageSize);
            List list = service.list(objectQueryWrapper);
            list.parallelStream().forEach(v->{
               //......
            });
        
        });

注意并发问题 iStart会被多个线程操作 所以用AtomicInteger来操作

2.Limit 优化

都知道limit 查询 在很大数据量下 越往后偏移速度越慢

优化

select *  from  A表 as a join (  select id  from A表 limit  offet,size ) as b  on b.id=a.id  

这sql可以通用啊,那我怎么加入到Mybatis plus里面啊

3.Mybatis plus SQL注入器

3.1自定义全局方法

关于自定义全局方法如何写 可以看官方的 案例

public class LimitMethod extends AbstractMethod {
    
    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        String id=tableInfo.getKeyColumn();
        String tableName = tableInfo.getTableName();
        String sql = String.format("<script> select * from %s as a join\n" +
                        "      (select %s from %s %s) as b on b.%s=a.%s  </script>", tableName,
                id, tableName,sqlComment(),id,id);
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        return addSelectMappedStatementForTable(mapperClass,"selectListByLimit",sqlSource,tableInfo);
    }
}

注意 < script >

3.2注册自定义全局方法


@Component
public class MyDefinedSqlInjector extends DefaultSqlInjector {


    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {

        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
        methodList.add(new LimitMethod());
        return methodList;
    }
}

3.3自定义Mapper

public interface CommonMapper<T> extends BaseMapper<T> {

    List<T> selectListByLimit(@Param("ew") Wrapper<T> queryWrapper);

}

然后 需要用这个的继承它即可

public interface AdviceMapper extends CommonMapper<Advice> {

}

3.4自定义Service

public interface CommonService<T> extends IService<T> {

   List<T> listByLimit(Wrapper<T> queryWrapper);

}
public class CommonServiceImpl<M extends CommonMapper<T>,T> extends ServiceImpl<M,T> implements CommonService<T> {

    @Override
    public List<T> listByLimit(Wrapper<T> queryWrapper) {
        return this.baseMapper.selectListByLimit(queryWrapper);
    }

}
public interface AdviceService extends CommonService<Advice> {

}
public class AdviceServiceImpl extends CommonServiceImpl<AdviceMapper, Advice> implements AdviceService {

}

3.5使用

        int count= service.count();
        int pageSize=10000;
        int pageNum=(count/pageSize)+1;
        AtomicInteger iStart = new AtomicInteger(0);
        final String limit="limit ";
        Stream<Integer> iterate = Stream.iterate(0, i -> ++i);
        iterate.limit(pageNum).parallel().forEach(integer -> {
            QueryWrapper<Object> objectQueryWrapper = new QueryWrapper<>();
            objectQueryWrapper.last(limit+ iStart.getAndAdd(pageSize) +","+pageSize);
            List list = service.list(objectQueryWrapper);
            list.parallelStream().forEach(v->{
               //......
            });
        
        });
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值