大數據量分批執行封裝


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表達式,可以節省大量代碼,且不用費心思創建類給它取名字,還是很好用的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM