1. 大資料量分批執行封裝
1.1. 前言
在執行定時任務的時候,我們常常會有這樣的需求,當資料量越來越大,可能你一次查詢的資料就會導致記憶體溢位,所以我們后期往往又要再不斷優化,比如分批處理,但分頁以后代碼量往往呈直線上升,且結構混亂更加復雜難懂,對此我就想寫個封裝方法,解決任何的分批資料庫查詢
1.2. 思路
事實上,分頁等操作都是固定套路,我們只需要把查詢整體資料及頁數,還有如何處理每一批資料抽象出來即可
1.3. 實作
- 封裝了一個靜態方法工具(依賴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());
}
}
- 使用舉例,第一個引數寫查詢所有資料的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運算式,可以節省大量代碼,且不用費心思創建類給它取名字,還是很好用的
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/155294.html
標籤:Java
