日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

實現百萬級數據從Excel導入到數據庫的方式

來源: 責編: 時間:2024-04-09 17:21:06 221觀看
導讀高手回答場景分析這個案例實際上涉及到多個方面,需要我們系統地分析。讓我們首先看看,從Excel中讀取百萬級數據并將其插入數據庫時可能遇到的問題:內存溢出風險加載如此龐大的Excel數據可能導致內存溢出,需要注意內存管理

高手回答

場景分析

這個案例實際上涉及到多個方面,需要我們系統地分析。讓我們首先看看,從Excel中讀取百萬級數據并將其插入數據庫時可能遇到的問題:7L528資訊網——每日最新資訊28at.com

  1. 內存溢出風險

加載如此龐大的Excel數據可能導致內存溢出,需要注意內存管理。7L528資訊網——每日最新資訊28at.com

  1. 性能瓶頸

處理百萬級數據的讀取和插入操作可能很耗時,性能優化至關重要。7L528資訊網——每日最新資訊28at.com

  1. 異常處理策略

讀取和導入過程中會有各種潛在問題,我們需妥善處理各類異常情況。7L528資訊網——每日最新資訊28at.com

內存溢出問題

處理百萬級數據,直接加載到內存中顯然不現實。解決之道在于采用流式讀取,分批處理數據。7L528資訊網——每日最新資訊28at.com

在技術選型上,選擇EasyExcel是明智之舉。它專為處理大數據量和復雜Excel文件進行了優化。EasyExcel在解析Excel時,不會將整個文件一次性加載到內存中,而是按行從磁盤逐個讀取數據并解析。7L528資訊網——每日最新資訊28at.com

性能問題

針對百萬級數據的處理,單線程顯然效率低下。提升性能的關鍵在于多線程處理。7L528資訊網——每日最新資訊28at.com

多線程應用涉及兩個場景:一是多線程讀取文件,另一個是多線程實現數據插入。這涉及到生產者-消費者模式,多線程讀取并多線程插入,以最大程度提升整體性能。7L528資訊網——每日最新資訊28at.com

在數據插入方面,除了利用多線程,還應當結合數據庫的批量插入功能以進一步提升速度。7L528資訊網——每日最新資訊28at.com

錯誤處理

在文件讀取和數據庫寫入過程中,可能遇到諸多問題,如數據格式錯誤、不一致性和重復數據等。7L528資訊網——每日最新資訊28at.com

因此,應分兩步處理。首先進行數據檢查,在插入操作前檢查數據格式等問題,然后在插入過程中處理異常情況。7L528資訊網——每日最新資訊28at.com

處理方式多種多樣,可通過事務回滾或記錄日志。一般不推薦直接回滾操作,而是自動重試,若嘗試多次仍無效,則記錄日志,隨后重新插入數據。7L528資訊網——每日最新資訊28at.com

此外,在這一過程中,需考慮數據重復問題,可在Excel中設定若干字段為數據庫唯一約束。遇到數據沖突時,可覆蓋、跳過或報錯處理。根據實際業務情況選擇合適的處理方式,一般情況下,跳過并記錄日志是相對合理的選擇。7L528資訊網——每日最新資訊28at.com

解決思路

所以,總體方案如下:7L528資訊網——每日最新資訊28at.com

利用EasyExcel進行Excel數據讀取,因其逐行讀取數據而非一次性加載整個文件至內存。為提高并發效率,將百萬級數據分布在不同的工作表中,利用線程池和多線程同時讀取各個工作表。在讀取過程中,借助EasyExcel的ReadListener進行數據處理。7L528資訊網——每日最新資訊28at.com

在處理過程中,并非每條數據都直接操作數據庫,以免對數據庫造成過大壓力。設定一個批次大小,例如每1000條數據,將從Excel中讀取的數據臨時存儲在內存中(可使用List實現)。每讀取1000條數據后,執行數據的批量插入操作,可簡單地借助mybatis實現批量插入。7L528資訊網——每日最新資訊28at.com

此外,在處理過程中,需要考慮并發問題,因此我們將使用線程安全的隊列來存儲內存中的臨時數據,如ConcurrentLinkedQueue。7L528資訊網——每日最新資訊28at.com

經驗證,通過上述方案,讀取并插入100萬條數據的Excel所需時間約為100秒,不超過2分鐘。7L528資訊網——每日最新資訊28at.com

具體實現

為了提升并發處理能力,我們將百萬級數據存儲在同一個Excel文件的不同工作表中,然后通過EasyExcel并發地讀取這些工作表數據。7L528資訊網——每日最新資訊28at.com

EasyExcel提供了ReadListener接口,允許在每批數據讀取后進行自定義處理。我們可以基于這一功能實現文件的分批讀取。7L528資訊網——每日最新資訊28at.com

pom依賴

首先,需要添加以下依賴:7L528資訊網——每日最新資訊28at.com

<dependencies>    <!-- EasyExcel -->    <dependency>        <groupId>com.alibaba</groupId>        <artifactId>easyexcel</artifactId>        <version>latest_version</version>    </dependency>    <!-- 數據庫連接和線程池 -->    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-data-jpa</artifactId>    </dependency></dependencies>

并發讀取多個sheet

然后實現并發讀取多個sheet的代碼:7L528資訊網——每日最新資訊28at.com

@Servicepublic class ExcelImporterService {    @Autowired    private MyDataService myDataService;        public void doImport() {        // Excel文件的路徑        String filePath = "users/paidaxing/workspace/excel/test.xlsx";        // 需要讀取的sheet數量        int numberOfSheets = 20;        // 創建一個固定大小的線程池,大小與sheet數量相同        ExecutorService executor = Executors.newFixedThreadPool(numberOfSheets);        // 遍歷所有sheets        for (int sheetNo = 0; sheetNo < numberOfSheets; sheetNo++) {            // 在Java lambda表達式中使用的變量需要是final            int finalSheetNo = sheetNo;            // 向線程池提交一個任務            executor.submit(() -> {                // 使用EasyExcel讀取指定的sheet                EasyExcel.read(filePath, MyDataModel.class, new MyDataModelListener(myDataService))                         .sheet(finalSheetNo) // 指定sheet號                         .doRead(); // 開始讀取操作            });        }        // 啟動線程池的關閉序列  executor.shutdown();        // 等待所有任務完成,或者在等待超時前被中斷        try {            executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);        } catch (InterruptedException e) {            // 如果等待過程中線程被中斷,打印異常信息            e.printStackTrace();        }    }}

這段代碼通過創建一個固定大小的線程池來并發讀取一個包含多個sheets的Excel文件。每個sheet的讀取作為一個單獨的任務提交給線程池。7L528資訊網——每日最新資訊28at.com

我們在代碼中用了一個MyDataModelListener,這個類是ReadListener的一個實現類。當EasyExcel讀取每一行數據時,它會自動調用我們傳入的這個ReadListener實例的invoke方法。在這個方法中,我們就可以定義如何處理這些數據。7L528資訊網——每日最新資訊28at.com

MyDataModelListener還包含doAfterAllAnalysed方法,這個方法在所有數據都讀取完畢后被調用。這里可以執行一些清理工作,或處理剩余的數據。7L528資訊網——每日最新資訊28at.com

ReadListener

接下來,我們來實現這個我們的ReadListener:7L528資訊網——每日最新資訊28at.com

import com.alibaba.excel.context.AnalysisContext;import com.alibaba.excel.read.listener.ReadListener;import org.springframework.transaction.annotation.Transactional;import java.util.ArrayList;import java.util.List;// 自定義的ReadListener,用于處理從Excel讀取的數據public class MyDataModelListener implements ReadListener<MyDataModel> {    // 設置批量處理的數據大小    private static final int BATCH_SIZE = 1000;    // 用于暫存讀取的數據,直到達到批量大小    private List<MyDataModel> batch = new ArrayList<>();        private MyDataService myDataService;    // 構造函數,注入MyBatis的Mapper    public MyDataModelListener(MyDataService myDataService) {        this.myDataService = myDataService;    }    // 每讀取一行數據都會調用此方法    @Override    public void invoke(MyDataModel data, AnalysisContext context) {        //檢查數據的合法性及有效性        if (validateData(data)) {            //有效數據添加到list中            batch.add(data);        } else {            // 處理無效數據,例如記錄日志或跳過        }                // 當達到批量大小時,處理這批數據        if (batch.size() >= BATCH_SIZE) {            processBatch();        }    }        private boolean validateData(MyDataModel data) {        // 調用mapper方法來檢查數據庫中是否已存在該數據        int count = myDataService.countByColumn1(data.getColumn1());        // 如果count為0,表示數據不存在,返回true;否則返回false        if(count == 0){         return true;        }                // 在這里實現數據驗證邏輯        return false;    }    // 所有數據讀取完成后調用此方法    @Override    public void doAfterAllAnalysed(AnalysisContext context) {        // 如果還有未處理的數據,進行處理        if (!batch.isEmpty()) {            processBatch();        }    }    // 處理一批數據的方法    private void processBatch() {        int retryCount = 0;        // 重試邏輯        while (retryCount < 3) {            try {                // 嘗試批量插入                myDataService.batchInsert(batch);                // 清空批量數據,以便下一次批量處理                batch.clear();                break;            } catch (Exception e) {                // 重試計數增加                retryCount++;                // 如果重試3次都失敗,記錄錯誤日志                if (retryCount >= 3) {                    logError(e, batch);                }}

通過自定義MyDataModelListener,在讀取Excel文件過程中可實現數據處理。每讀取一條數據后,將其加入列表,在列表累積達到1000條時,執行一次數據庫批量插入操作。若插入失敗,則進行重試;若多次嘗試仍失敗,則記錄錯誤日志。7L528資訊網——每日最新資訊28at.com

批量插入

這里批量插入,用到了MyBatis的批量插入,代碼實現如下:7L528資訊網——每日最新資訊28at.com

import org.apache.ibatis.annotations.Mapper;import java.util.List;@Mapperpublic interface MyDataMapper {    void batchInsert(List<MyDataModel> dataList);    int countByColumn1(String column1);}

mapper.xml文件:7L528資訊網——每日最新資訊28at.com

<insert id="batchInsert" parameterType="list">    INSERT INTO paidaxing_test_table_name (column1, column2, ...)    VALUES     <foreach collection="list" item="item" index="index" separator=",">        (#{item.column1}, #{item.column2}, ...)    </foreach></insert><select id="countByColumn1" resultType="int">    SELECT COUNT(*) FROM your_table WHERE column1 = #{column1}</select>


7L528資訊網——每日最新資訊28at.com


7L528資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-82361-0.html實現百萬級數據從Excel導入到數據庫的方式

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 您必須了解的 21 個 HTML 技巧

下一篇: Rust命名規范的最佳實踐,你學會了嗎?

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
国产精品久久久久三级| 亚洲网站啪啪| 一区精品久久| 亚洲电影自拍| 亚洲免费观看高清完整版在线观看熊| 亚洲免费观看高清完整版在线观看熊 | 亚洲深夜av| 亚洲欧美精品在线观看| 久久不射电影网| 蜜桃久久av一区| 欧美日韩久久不卡| 国产精品一区在线观看| 在线欧美视频| 亚洲深夜福利视频| 久久久久国产成人精品亚洲午夜| 免费在线欧美黄色| 欧美日韩成人综合天天影院| 国产精品成人在线| 极品av少妇一区二区| 日韩西西人体444www| 亚洲欧美中文字幕| 麻豆乱码国产一区二区三区| 欧美视频在线观看免费网址| 国产日韩精品在线| 亚洲免费观看高清在线观看| 欧美一区二区三区在线观看| 欧美精品日韩三级| 国产亚洲欧美日韩美女| 亚洲最新视频在线| 久久久久久久尹人综合网亚洲| 欧美日韩精品在线播放| 国产一区二区日韩精品| 日韩视频免费观看高清在线视频 | 欧美午夜不卡影院在线观看完整版免费| 国产精品中文在线| 亚洲伦理自拍| 久久国产精品免费一区| 欧美视频在线观看免费| 亚洲国产高清在线| 午夜日韩av| 欧美日韩妖精视频| 亚洲电影av在线| 欧美一区二区三区在线看 | 国产日韩欧美在线播放| 日韩一区二区精品| 久久综合中文| 国产日韩高清一区二区三区在线| 亚洲伦理一区| 美女视频黄免费的久久| 国产美女在线精品免费观看| 日韩午夜在线电影| 欧美成人高清视频| 国产午夜精品一区理论片飘花| 一区二区三区视频在线观看| 蜜桃av噜噜一区| 国内激情久久| 性欧美暴力猛交69hd| 欧美丝袜一区二区三区| 91久久中文字幕| 久久一区二区三区四区| 国产精品视频精品| 亚洲午夜精品一区二区三区他趣| 欧美黑人多人双交| 亚洲国产99精品国自产| 久久久国产视频91| 国产一区二区三区直播精品电影| 亚洲字幕一区二区| 欧美午夜电影在线观看| 亚洲三级电影全部在线观看高清| 久久久久久自在自线| 国产欧美视频一区二区三区| 亚洲欧美日韩国产另类专区| 欧美午夜精品理论片a级大开眼界 欧美午夜精品理论片a级按摩 | 国产视频精品网| 中文国产一区| 欧美午夜在线| 这里只有视频精品| 欧美日韩在线观看一区二区三区| 91久久中文| 欧美国产视频在线| 亚洲精品一区二区三区福利| 欧美成人免费观看| 亚洲激情电影中文字幕| 欧美成人免费在线| 亚洲激情一区二区三区| 欧美成人蜜桃| 亚洲精品国产精品国自产观看浪潮| 麻豆freexxxx性91精品| 亚洲电影免费在线观看| 免费欧美日韩国产三级电影| 永久免费视频成人| 欧美jizzhd精品欧美巨大免费| 亚洲国产精品综合| 欧美高清自拍一区| 日韩一级黄色av| 欧美视频国产精品| 亚洲欧美日韩国产综合精品二区| 国产欧美日韩一区二区三区在线观看 | 国产午夜精品全部视频播放| 久久精品99国产精品日本| 黄色小说综合网站| 老司机亚洲精品| 亚洲人成在线播放网站岛国| 欧美精品啪啪| 亚洲无玛一区| 国产欧美日韩视频| 老巨人导航500精品| 91久久精品日日躁夜夜躁国产| 欧美人与性动交cc0o| 亚洲天堂免费在线观看视频| 国产欧美精品日韩区二区麻豆天美| 欧美中文字幕在线| 亚洲成人原创| 欧美区在线观看| 亚洲欧美资源在线| 一区久久精品| 欧美日韩mp4| 欧美亚洲在线观看| 亚洲第一网站免费视频| 欧美色精品在线视频| 欧美一站二站| 亚洲激情网站免费观看| 国产精品xvideos88| 久久gogo国模啪啪人体图| 亚洲高清免费| 欧美性色综合| 久久久五月婷婷| 99精品欧美一区| 国产亚洲精品福利| 欧美激情免费在线| 午夜久久影院| 亚洲国产影院| 国产精品人人做人人爽人人添| 久久九九免费| 一区二区三区精品视频| 国产一区二区三区精品久久久| 欧美电影在线观看完整版| 亚洲综合成人婷婷小说| 亚洲承认在线| 国产精品视频免费| 免费视频亚洲| 午夜精品亚洲| 亚洲区欧美区| 国产视频观看一区| 欧美日本不卡高清| 久久久久免费视频| 亚洲一区二区黄| 亚洲国产成人高清精品| 国产精品毛片一区二区三区| 男人的天堂亚洲在线| 亚洲欧美另类久久久精品2019| 亚洲国产成人精品视频| 国产精品日韩在线一区| 欧美顶级大胆免费视频| 欧美在线视频网站| 一区二区三区欧美视频| 在线日韩av永久免费观看| 国产久一道中文一区| 欧美激情欧美狂野欧美精品| 欧美一级淫片播放口| 99精品视频免费观看| 尤物yw午夜国产精品视频| 国产精品久久久久999| 欧美va亚洲va香蕉在线| 久久精品中文| 亚洲欧美日韩人成在线播放| 亚洲另类黄色| 在线免费观看欧美| 国产一区二区三区精品欧美日韩一区二区三区 | 欧美天堂亚洲电影院在线播放| 久久先锋影音| 久久国产精品久久精品国产| 亚洲一区二区免费在线| 亚洲免费福利视频| 亚洲黄色成人久久久| 国内精品久久久久久| 国产麻豆精品在线观看| 欧美色欧美亚洲另类二区| 欧美成人小视频| 久久亚洲国产精品一区二区 | 亚洲自拍都市欧美小说| 99精品欧美一区二区三区综合在线| 在线成人h网| 国内精品久久国产| 国产日本欧美视频| 国产精品免费电影| 欧美午夜视频一区二区| 欧美日韩精品一区二区在线播放 | 亚洲精品网站在线播放gif| 在线观看一区二区精品视频| 国产偷国产偷精品高清尤物| 国产精品网站在线| 国产精品毛片在线| 国产精品毛片va一区二区三区 | 裸体丰满少妇做受久久99精品| 久久精品视频免费播放| 久久99在线观看| 欧美专区福利在线| 欧美在线播放视频| 久久福利影视| 久久精品在线播放| 久久婷婷麻豆| 蜜桃久久精品一区二区| 你懂的亚洲视频|