Java 使用ListUtils對List分頁處理


背景分析

  工作中,經常遇到需要用Java進行分頁處理數據,例如把1000萬條Excel數據寫入MySQL數據庫,如果把這1000w數據一股腦的丟給MySQL,保證把數據庫玩完,故需要批量寫入,如每批次寫入500條。這時候就可以使用ListUtils.partition了。

maven坐標

  commons-collections4和Guava兩個jar包的坐標如下:

<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-collections4</artifactId>
	<version>4.4</version>
</dependency>
<dependency>
	<groupId>com.google.guava</groupId>
	<artifactId>guava</artifactId>
	<version>31.0.1-jre</version>
</dependency>

批處理List

  基於commons-collections4和Guava兩個jar包,對java.util.List中海量數據進行分批處理的邏輯如下所示,請求參數都是傳入List和每頁處理的數據量:

    public static void main(String[] args) {
        List<String> list =new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("Wiener");
        batchDealData(list, 3);
        batchDealByGuava(list, 3);
    }

    private static void batchDealData (List data, int batchNum) {

        // commons-collections4
        List<List<String>> partitions = ListUtils.partition(data, batchNum);
        partitions.stream().forEach(sublist -> {
            System.out.println(sublist);
        });
    }
    private static void batchDealByGuava (List data, int batchNum) {
        // guava
        List<List<String>> partitions = Lists.partition(data, batchNum);
        partitions.stream().forEach(sublist -> {
            System.out.println(sublist);
        });
    }

  這種處理方法相對於手動分頁,其優點顯而易見,既可以降低代碼復雜度,又可以提高開發效率。小編在《Java 使用線程池分批插入或者更新數據》中,介紹了一種通用分頁方式,略顯復雜,下面基於commons-collections4,優化其中的分頁策略,代碼如下:

private void batchDeal(List<Object> data, int batchNum) throws InterruptedException {
        if (CollectionUtils.isEmpty(data)) {
            return;
        }
        // 使用 ListUtils.partition分頁
        List<List<Object>> newList = ListUtils.partition(data, batchNum);
        // 計算總頁數
        int pageNum = newList.size(); 
        ExecutorService executor = Executors.newFixedThreadPool(pageNum);
        try {
            CountDownLatch countDownLatch = new CountDownLatch(pageNum);
            for (int i = 0; i < pageNum; i++) {
                ImportTask task = new ImportTask(newList.get(i), countDownLatch);
                executor.execute(task);
            }
            countDownLatch.await();
            log.info("數據操作完成!可以在此開始其它業務");
        } finally {
            // 關閉線程池,釋放資源
            executor.shutdown();
        }
    }
    // 無改動
    class ImportTask implements Runnable {
        private List list;
        private CountDownLatch countDownLatch;

        public ImportTask(List data, CountDownLatch countDownLatch) {
            this.list = data;
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            if (null != list) {
                // 業務邏輯,例如批量insert或者update
                log.info("現在操作的數據是{}", list);
            }
            // 發出線程任務完成的信號
            countDownLatch.countDown();
        }
    }

小結

   你如果對於如何分頁不熟練,使用如上分頁技術進行處理,是不是很簡單?如果你有更輕巧的方法,歡迎留言評論。


免責聲明!

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



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