Java web 大数据量数据库操作批处理工具类

Posted 李泰山

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java web 大数据量数据库操作批处理工具类相关的知识,希望对你有一定的参考价值。

前言

当操作大量数据的时候往往需要分批次去处理,以减少内存和i/o的压力,比如用 mybatis-plus,添加、修改、查询大量数据时候,会造成数据库压力太大,导致服务异常,还有在执行sql 的in 方法时候,参数不能大于1000个等问题,都需要进行批量处理。下面整理一个BatchUtil 批处理工具类,很好的解决以上的问题。

 工具类代码


import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
/**
 *  批处理工具类
 *
 * @version 1.0
 * @since JDK1.8
 * @author tarzan
 * @date 2022年01月28日 16:39:50
 */
public class BatchUtil 

    /**
     * 批次数量
     */
    public static final Integer NUMBER_BACH_PROTECT = 999;


    /**
     * 批量中包含有关联查询,可能因为数据过长出现数据查询的的问题,
     * 这里进行分批处理
     * @param list
     * 需要处理的list
     * @param bach
     * 批量处理的函数
     * @param <T>
     *     元素类型
     */
    public static <T> void protectBach(List<T> list, Consumer<List<T>> bach)
        if (isEmpty(list))return;
        if (list.size() > NUMBER_BACH_PROTECT) 
            for (int i = 0; i < list.size(); i += NUMBER_BACH_PROTECT) 
                int lastIndex = Math.min(i + NUMBER_BACH_PROTECT, list.size());
                bach.accept(list.subList(i, lastIndex));
            
        else 
            bach.accept(list);
        
    

    /**
     * 批量中包含有关联查询,可能因为数据过长出现数据查询的的问题
     * 这里进行分批,合并数据处理。
     * @param list
     *  原数据
     * @param bach
     *  处理方法
     * @param <T>
     *     原数据类型
     * @param <R>
     *     处理结果类型
     * @return
     *  处理结果汇总
     */
    public static <T, R> List<R> protectBach(List<T> list, Function<List<T>, List<R>> bach)
        if (isEmpty(list))return Collections.emptyList();
        if (list.size() > NUMBER_BACH_PROTECT) 
            List<R> end = new LinkedList<>();
            for (int i = 0; i < list.size(); i += NUMBER_BACH_PROTECT) 
                int lastIndex = Math.min(i + NUMBER_BACH_PROTECT, list.size());
                Optional.ofNullable(bach.apply(list.subList(i, lastIndex)))
                        .ifPresent(end::addAll);
            
            return end;
        
        return bach.apply(list);
    

    private static <T> boolean isEmpty(Collection<T> collection) 
        return collection == null || collection.isEmpty();
    



使用教程

比如 数据操作A和B表,A表是主表,B是子表,当批量删除A表的数据,同时删除B表关联的数据,代码如下


    /**
     * 方法描述: 删除
     *
     * @param ids
     * @return @link boolean
     */
    @Transactional(rollbackFor = Throwable.class)
    public boolean delete(List<Long> ids) 
        if(CollectionUtils.isEmpty(ids))
            return true;
        
        removeByIds(ids);
       return attributeSetService.deleteByClazz(ids);
    

    /**
     * 方法描述: 根据要素集删除
     *
     * @param setIds
     * @return @link boolean
     */
    @Transactional(rollbackFor = Throwable.class)
    protected boolean delBySets(List<Long> setIds) 
        LambdaQueryWrapper<FeatureClazzEntity> wrapper=new LambdaQueryWrapper();
        wrapper.select(FeatureClazzEntity::getId).in(FeatureClazzEntity::getFeatureSetId,setIds);
        List<Long> ids=list(wrapper).stream().map(FeatureClazzEntity::getId).collect(Collectors.toList());
        BatchUtil.protectBach(ids, this::delete);
        return true;
    

 批量查询

比如 数据操作A和B表,A表是主表,B是子表,根据A表的数据,查出B表关联的数据,代码如下

    protected List<AttributeSetEntity> selectBySets(List<Long> setIds) 
        LambdaQueryWrapper<FeatureClazzEntity> wrapper=new LambdaQueryWrapper();
        wrapper.select(FeatureClazzEntity::getId).in(FeatureClazzEntity::getFeatureSetId,setIds);
        List<Long> ids=list(wrapper).stream().map(FeatureClazzEntity::getId).collect(Collectors.toList());
        List<AttributeSetEntity> result= BatchUtil.protectBach(ids, idList->
            return attributeSetService.lambdaQuery().in(AttributeSetEntity::getClazzId,idList).list();
        );
        return result;
    

以上是关于Java web 大数据量数据库操作批处理工具类的主要内容,如果未能解决你的问题,请参考以下文章

JDBC--05--MySQL大数据量操作---常规查询游标查询流式查询,

web平台大数据请求传输性能处理

MyBatis-Plus对于大数据量查询,采用分页查询按批次处理结果,通用工具封装

MyBatis-Plus对于大数据量查询,采用分页查询按批次处理结果,通用工具封装

大数据必学Java基础(二十八):Arrays工具类和数组的复制操作

大数据平台常见开源工具有哪些?