zoukankan      html  css  js  c++  java
  • 大数据量分批执行封装

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

    1.1. 前言

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

    1.2. 思路

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

    1.3. 实现

    1. 封装了一个静态方法工具(依赖Mybatis
    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(方法内会做分页),第二个参数即第一个参数的返回结果处理,比如我这里更新一个字段,第三个参数为可选项,分批查询每次查几条
        @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表达式,可以节省大量代码,且不用费心思创建类给它取名字,还是很好用的

  • 相关阅读:
    《剑指offer》— JavaScript(1)二维数组中的查找
    《JavaScript高级程序设计(第三版)》-3
    HTML+CSS基础
    HTML5新增属性
    《javascript高级程序设计(第3版)》-1
    wp8.1 Study7: ListView 和GridView应用
    wp8.1 Study6: App的生命周期管理
    WP8.1 Study5:Data binding数据绑定
    WP8.1 Study4:WP8.1中控件集合应用
    WP8.1 Study3:WP8.1中Animation应用
  • 原文地址:https://www.cnblogs.com/sky-chen/p/13207693.html
Copyright © 2011-2022 走看看