数据库大数据量处理方法启用游标查询
 1,可以防止数据库一下返回过大,导致OOM,超时(超过数据库限制),效果类似分页查询
 2,需要开启事务---分批查询的缘故
 

大数据量查询:

1,使用游标查询---避免内存泄漏 
mybatis-plus在一次查询量超过百万级别的时候,容易出现内存泄漏,此时可以使用游标查询,逐条查询(查询完就释放内存 fetchSize = 100000 
每次获取的条数,获取完就释放),并且在游标关闭的时候也会释放游标本身即最后一次查询的内存

2,使用流式查询---避免内存泄漏
3,要加@Transactional否则报游标关闭    

@Transactional
    @Override
    public List<HHDto> getHNoPage(HRequest hRequest) {
        List<HH> result = new ArrayList<>();
        List<HH> resultTmp = new ArrayList<>();
        List<HHDto> resultDto = new ArrayList<>();
        List<Long> matchingIds = hRequest.getMatchingId();
        Long segmentId = hRequest.getSegmentId();
        Long lastId = hRequest.getLatestId();
        Long begin = hRequest.getBegin();
        Long limit = hRequest.getLimit();
        Integer taskType = hRequest.getTaskType();
        String taskId = hRequest.getTaskId();
        Cursor<HH> domainList =null;
        try{
            QueryWrapper<HH> query = new QueryWrapper<>();
            if(null != matchingIds && matchingIds.size()>0){
                query.in("m",matchingIds);
            }
            if(null !=segmentId){
                query.eq("s",segmentId);
            }
            if(null != begin && null != limit){
                    query.gt("id",begin);
                query.last("limit "+limit);
            }
            if(null !=taskType){
                query.eq("t",taskType);
            }
            if(null !=taskId){
                query.eq("t_id",taskId);
            }
            MyExport myExport = new MyExport();
            domainList = HHMapper.listData(query,myExport);
            Iterator<HH> iter = domainList.iterator();
            int num=0;
            while (iter.hasNext()){
//                HH tmp =iter.next();
                rebuildBo(resultDto, iter.next());
//                result.add(tmp);
                num++;
            }
            if(num == 0){
                log.info("没有对应条件的查询结果:sid:{},mid:{}",sId,mIds);
            }else{
                log.info("getHNoPage数据库查询结果数:{}",num);
            }


            result =null;

        }catch (Exception e){
            log.error("根据mId查询HH失败,条件:{},异常:{}",mIds,e.getMessage(),e);
        }finally {
            if (null != domainList) {
                try {
                    domainList.close();
                } catch (Exception e) {
                    log.error("根据matchIngId查询HH游标关闭失败:{}",e.getMessage(), e);
                }
            }
        }
        return resultDto;
    }
    
    
    


import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;


public class MyExport implements ResultHandler {
    
    @Override
    public void handleResult(ResultContext resultContext) {
        Object resultObject = resultContext.getResultObject();
        System.out.println(resultObject.toString());
    }
}
 
 @Select("SELECT bds.* FROM cs bds ${ew.customSqlSegment} ")
    @Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 100000)
    @ResultType(HBo.class)
    Cursor<HBo> listData(@Param(Constants.WRAPPER) QueryWrapper<HBo> queryWrapper, ResultHandler<HBo> handler);

 
 

更多推荐