前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大数据量分批执行封装

大数据量分批执行封装

作者头像
老梁
发布2020-07-01 10:32:09
8620
发布2020-07-01 10:32:09
举报
文章被收录于专栏:Java工程师成长之路

1. 大数据量分批执行封装

1.1. 前言

在执行定时任务的时候,我们常常会有这样的需求,当数据量越来越大,可能你一次查询的数据就会导致内存溢出,所以我们后期往往又要再不断优化,比如分批处理,但分页以后代码量往往呈直线上升,且结构混乱更加复杂难懂,对此我就想写个封装方法,解决任何的分批数据库查询

1.2. 思路

事实上,分页等操作都是固定套路,我们只需要把查询整体数据及页数,还有如何处理每一批数据抽象出来即可

1.3. 实现

  1. 封装了一个静态方法工具(依赖Mybatis
代码语言:javascript
复制
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;

import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * @author: laoliangliang
 * @description: 批量执行工具
 * @create: 2020/6/29 9:52
 **/
@Slf4j
public class BatchUtil {

    /**
     * @param supplier 获取总数据
     * @param consumer 消费分数据
     */
    public static <T> void execute(Supplier<List<T>> supplier, Consumer<List<T>> consumer) {
        execute(supplier, consumer, 1000);
    }

    public static <T> void execute(Supplier<List<T>> supplier, Consumer<List<T>> consumer, int pageSize) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        boolean first = true;
        long total = 1;
        for (int i = 0; i < total; i++) {
            Page<Object> objects = PageHelper.startPage(i + 1, pageSize);
            if (!first) {
                objects.setCount(false);
            }
            List<T> list = supplier.get();
            if (first) {
                total = objects.getPages();
                first = false;
            }
            consumer.accept(list);
        }
        stopWatch.stop();
        log.info("耗时:{}秒", stopWatch.getTotalTimeSeconds());
    }
}
  1. 使用举例,第一个参数写查询所有数据的sql(方法内会做分页),第二个参数即第一个参数的返回结果处理,比如我这里更新一个字段,第三个参数为可选项,分批查询每次查几条
代码语言:javascript
复制
    @Test
    public void updateUserNos() {
        BatchUtil.execute(()-> userMapper.selectAll(), users->{
            for (User user : users) {
                User userUpdate = new User();
                userUpdate.setId(user.getId());
                userUpdate.setUserNo(MD5Util.getUserNo(user.getPhone()));
                userMapper.updateByPrimaryKeySelective(user);
            }
        },10000);
    }

1.4. 总结

抽象这样的工具方法,用Java8的lambda表达式,可以节省大量代码,且不用费心思创建类给它取名字,还是很好用的

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-06-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 大数据量分批执行封装
    • 1.1. 前言
      • 1.2. 思路
        • 1.3. 实现
          • 1.4. 总结
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档