ThreadPoolExecutor實現批量插入


一:在run()方法里寫插入

 1 package com.smartdata.pms.thread;
 2 
 3 import com.smartdata.pms.entity.PmsProduct;
 4 import com.smartdata.pms.mapper.PmsProductMapper;
 5 import lombok.extern.slf4j.Slf4j;
 6 
 7 import java.util.List;
 8 
 9 /**
10  * @ProjectName: smartdata
11  * @Package: com.smartdata.pms.thread
12  * @ClassName: InsertBatchRun
13  * @Author: heluwei
14  * @Description:
15  * @Date: 2020/3/22 16:36
16  * @Version: 1.0
17  */
18 @Slf4j
19 public class InsertBatchRun implements Runnable {
20     //數據層訪問
21     private PmsProductMapper pmsProductMapper;
22     //具體插入批次
23     private int batch;
24 
25     //插入的數據
26     private List<PmsProduct> list;
27 
28     public InsertBatchRun(PmsProductMapper pmsProductMapper,List<PmsProduct> list,int batch) {
29         this.pmsProductMapper = pmsProductMapper;
30         this.list = list;
31         this.batch = batch;
32     }
33     @Override
34     public void run() {
35         try {
36             for(int i=0;i<list.size();i++){
37                 this.pmsProductMapper.insert(list.get(i));
38             }
39             log.info("第" + this.batch + "批次插入成功");
40         } catch (Exception e) {
41             log.error("第" + this.batch + "批次插入失敗");
42         }
43 
44     }
45 }

注意:在使用***Mapper的時候。不能使用@Autowired,因為多線程環境下,防止注入。

二:使用線程池

 1 package com.smartdata.pms.utils;
 2 
 3 import com.smartdata.pms.entity.PmsProduct;
 4 import com.smartdata.pms.mapper.PmsProductMapper;
 5 import com.smartdata.pms.thread.InsertBatchRun;
 6 import lombok.extern.slf4j.Slf4j;
 7 
 8 import java.util.List;
 9 import java.util.concurrent.ArrayBlockingQueue;
10 import java.util.concurrent.ThreadPoolExecutor;
11 import java.util.concurrent.TimeUnit;
12 
13 /**
14  * @ProjectName: smartdata
15  * @Package: com.smartdata.pms.utils
16  * @ClassName: ExecutorUtils
17  * @Author: heluwei
18  * @Description:
19  * @Date: 2020/3/22 16:39
20  * @Version: 1.0
21  */
22 @Slf4j
23 public class ExecutorUtils {
24     private static final int CORE_POOL_SIZE = 5; //核心線程數為 5
25     private static final int MAX_POOL_SIZE = 10; //最大線程數 10
26     private static final int QUEUE_CAPACITY = 100; //
27     private static final Long KEEP_ALIVE_TIME = 1L; //當線程數大於核心線程數時,多余的空閑線程存活的最長時間
28 
29     public static void executeThreadPool(PmsProductMapper pmsProductMapper,  List<PmsProduct> pmsProductList){
30         //使用阿里巴巴推薦的創建線程池的方式
31         //通過ThreadPoolExecutor構造函數自定義參數創建
32         ThreadPoolExecutor executor = new ThreadPoolExecutor(
33                 CORE_POOL_SIZE,
34                 MAX_POOL_SIZE,
35                 KEEP_ALIVE_TIME, //當線程數大於核心線程數時,多余的空閑線程存活的最長時間
36                 TimeUnit.SECONDS, //時間單位
37                 new ArrayBlockingQueue<>(QUEUE_CAPACITY), //任務隊列,用來儲存等待執行任務的隊列
38                 new ThreadPoolExecutor.CallerRunsPolicy()); //飽和策略,簡單點說就是后面排隊的線程就在那兒等着。
39         //被拒絕的任務在主線程中運行,所以主線程就被阻塞了,別的任務只能在被拒絕的任務執行完之后才會繼續被提交到線程池執行
40         long start = System.currentTimeMillis();
41         //計數器
42         int size = 0;
43         for (int i = 0; i < (Math.round((pmsProductList.size() / 2000)+0.5)); i++) {
44             int startLen = i * 2000;
45             int endLen = ((i + 1) * 2000 > pmsProductList.size() ? pmsProductList.size() - 1 : (i + 1) * 2000);
46             List<PmsProduct> threadList = pmsProductList.subList(startLen, endLen);
47             size = size + threadList.size();
48             executor.execute(new InsertBatchRun(pmsProductMapper, threadList, i));
49         }
50         System.err.println("插入數據總條數:" + size);
51         long end = System.currentTimeMillis();
52         log.error("查詢耗時:" + (end - start));
53 
54         //終止線程池
55         // void shutdown() 啟動一次順序關閉,執行以前提交的任務,但不接受新任務。若已經關閉,則調用沒有其他作用。
56         executor.shutdown();
57         //boolean isTerminated()
58         //若關閉后所有任務都已完成,則返回true。注意除非首先調用shutdown或shutdownNow,否則isTerminated永不為true。
59         while (!executor.isTerminated()) {
60             //System.out.println("線程池還沒有完全關閉!!!");
61         }
62         log.info("插入完成:"+(end - start));
63     }
64 }

三:要導入的信息

 1 @SysLog("導入商品")
 2     @PostMapping("importProduct")
 3     public R importProduct(@RequestParam(value = "file", required = false) MultipartFile excelFile) {
 4         //============================使用模板======================================================
 5         InputStream inputStream = null;
 6         try {
 7             // 使用模板導入——接收上傳文件
 8             inputStream = excelFile.getInputStream();
 9             // 讀取表格數據
10             List<PmsProduct> pmsProductList = EasyExcel.read(inputStream, PmsProduct.class, null).headRowNumber(1).sheet(0).doReadSync();
11             // TODO 根據業務處理objectList……
12  ExecutorUtils.executeThreadPool(pmsProductMapper,pmsProductList); 13             /*pmsProductList.forEach(pmsProduct -> {
14                 pmsProductService.save(pmsProduct);
15             });*/
16         } catch (IOException e) {
17             e.printStackTrace();
18         } finally {
19             if (inputStream != null) {
20                 try {
21                     inputStream.close();
22                 } catch (IOException e) {
23                     e.printStackTrace();
24                 }
25             }
26         }
27         return new R();
28     }

四:對應的實體類

 1 package com.smartdata.pms.entity;
 2 
 3 import com.alibaba.excel.annotation.ExcelIgnore;
 4 import com.alibaba.excel.annotation.ExcelProperty;
 5 import com.alibaba.excel.annotation.write.style.ColumnWidth;
 6 import com.baomidou.mybatisplus.annotation.IdType;
 7 import com.baomidou.mybatisplus.annotation.TableId;
 8 import com.baomidou.mybatisplus.annotation.TableLogic;
 9 import com.baomidou.mybatisplus.annotation.TableName;
10 import com.baomidou.mybatisplus.extension.activerecord.Model;
11 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
12 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
13 import lombok.Data;
14 import lombok.EqualsAndHashCode;
15 
16 import java.time.LocalDateTime;
17 
18 /**
19  * @ProjectName: smartdata
20  * @Package: com.smartdata.pms.entity
21  * @ClassName: PmsProduct
22  * @Author: heluwei
23  * @Description: 商品列表
24  * @Date: 2019/12/29 15:03
25  * @Version: 1.0
26  */
27 @Data
28 @EqualsAndHashCode(callSuper = true)
29 @TableName("pms_product")
30 public class PmsProduct extends Model<PmsProduct> {
31     private static final long serialVersionUID = 1L;
32     @TableId(value = "pro_id", type = IdType.AUTO)
33     @JsonSerialize(using = ToStringSerializer.class)//解決long精度丟失問題
34     @ExcelProperty(value = "序號",index = 0)
35     @ColumnWidth(35)
36     private Long proId;           //商品ID
37 
38     @ExcelProperty(value = "商品編號",index = 1)
39     @ColumnWidth(35)
40     private String proNo;       //商品名稱
41 
42     @ExcelProperty(value = "商品名稱",index = 2)
43     @ColumnWidth(35)
44     private String proName;       //商品編號
45 
46     @ExcelProperty(value = "商品價格",index = 3)
47     @ColumnWidth(35)
48     private Float proPrice;           //商品價格
49 
50     @ExcelProperty(value = "商品類別",index = 4)
51     @ColumnWidth(35)
52     private Long proCategoryId;           //商品類別
53 
54     @ExcelProperty(value = "商品描述",index = 5)
55     @ColumnWidth(35)
56     private String proDescription;          //商品描述
57 
58     @ExcelProperty(value = "商品圖片路徑",index = 6)
59     @ColumnWidth(35)
60     private String proImage;          //商品圖片路徑
61 
62     @ExcelProperty(value = "商品庫存",index = 7)
63     @ColumnWidth(35)
64     private Long proInventory ;            //商品庫存
65 
66     @ExcelProperty(value = "商品銷量",index = 8)
67     @ColumnWidth(35)
68     private Long proSail;             //商品銷量
69 
70     @ExcelProperty(value = "商品規格",index = 9)
71     @ColumnWidth(35)
72     private String proSize;           //商品規格
73 
74     @ExcelProperty(value = "是否熱銷",index = 10)
75     @ColumnWidth(35)
76     private String IsHot;          //是否熱銷 0是 ,-1不是
77 
78     @ExcelProperty(value = "是否推薦",index = 11)
79     @ColumnWidth(35)
80     private String IsReconnend;    //是否推薦 0是,-1不是
81 
82     @ExcelIgnore
83     private LocalDateTime proCreateTime;    //上架時間
84     @ExcelIgnore
85     private LocalDateTime proUpdateTime;
86     /**
87      * 是否刪除  -1:已刪除  0:正常
88      */
89     @TableLogic
90     @ExcelIgnore
91     private String delFlag;
92 }

Excel表:

 

 

在使用Math.ceil()函數的時候。5.013給我計算成了5.我想保存的是6.

解決方案:用四舍五入函數+0.5

double ceil = Math.round(5.013+0.5);輸出6.  

 五:前台

 1 //指定允許上傳的文件類型
 2         upload.render({
 3             elem: '#importFile'
 4             ,url: '/pms/pmsPro/importProduct'
 5             , method: 'POST'
 6             ,accept: 'file' //普通文件
 7             ,exts: 'xlsx' //只允許上傳壓縮文件
 8             , headers: {
 9                 Authorization: 'Bearer ' + access_token,
10             }
11             ,done: function(res){
12                 layer.msg(res.msg);
13                 layui.table.reload('lay-Product-list'); //重載表格
14             }
15         });

 


免責聲明!

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



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