工做中常常遇到分批處理的問題,好比將一個List列表中的數據分批次保存至數據庫中。若是列表中數據條目很大,好比1000萬條以上,mysql中 max_allowed_packet 所能容許的最大數據包量不支持如此大的數據量,這種狀況下一次性保存處理就會出現保存失敗。另外,過大的數據條目數量,在保存時也會致使性能降低。爲此手動批量處置就成爲了一種必須。這裏給出分批處理的代碼,方便之後直接使用。java
package com.lunyu.algorithm.service.base; import com.google.common.collect.Lists; import java.util.List; /** * @author lunyu * @since 2021/1/25 */ public class BaseService { /** * 每一個批次數據條目 */ private static final int BATCH_SIZE = 10; public static void main(String[] args){ List<Integer> list = Lists.newArrayList(); for (int i = 0; i < 23; i++){ list.add(i + 1); } // 獲取執行的輪次 int round = (list.size() - 1) / BATCH_SIZE; for (int i = 0; i <= round; i++){ // 求每一個批次起始位置 int fromIndex = i * BATCH_SIZE; int toIndex = (i + 1) * BATCH_SIZE; // 若是是最後一個批次,則不能越界 if (i == round){ toIndex = list.size(); } List<Integer> subList = list.subList(fromIndex, toIndex); // TODO: 對subList執行進一步要作的操做 System.out.println("輪次:" + i); subList.forEach(e -> { System.out.print(e + ","); }); System.out.println(); } } }
這裏有三個個注意的點,mysql
第一, 獲取輪次使用 (list.size() - 1) / BATCH_SIZE ,這是爲了方便將屬於同一個批次的數據同屬該批次。以代碼爲例,若是剛好有10個元素 1-10 (對應的座標點 0-9 ),咱們要把它們放置在同一個批次下, BATCH_SIZE = 10; ,那麼 list.size() - 1 = 9 ,剛好能夠使最後一個元素和前面全部的元素都在一個批次下,這個批次等於 0。sql
第二,循環的輪次爲 i <= round; ,這時爲了保證全部的批次都能訪問到。數據庫
第三, if (i == round) ,要保證最後一個批次的數據,在獲取時不能數組越界。數組