Procházet zdrojové kódy

物资导入(单线程版本每三千条批量导入 3000条十几秒,二万来条五分钟,十万条十八分钟)

sl před 1 rokem
rodič
revize
d8e65e6f57

+ 1 - 1
jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml

@@ -130,7 +130,7 @@ spring:
         connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
       datasource:
         master: ## 声明第一个数据源所需的数据
-          url: jdbc:mysql://152.136.206.27:3306/kezhikeshi?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+          url: jdbc:mysql://152.136.206.27:3306/kezhikeshi?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
           username: itdm-boot
           password: itdm-boot@2023
           driver-class-name: com.mysql.cj.jdbc.Driver

+ 2 - 2
jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml

@@ -136,12 +136,12 @@ spring:
           driver-class-name: com.mysql.cj.jdbc.Driver
 #          password: Xinxi513513
         slave:  # 第二个数据源
-          url: jdbc:mysql://127.0.0.1:3306/look?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+          url: jdbc:mysql://127.0.0.1:3306/look?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
           username: root
           password: Xinxi513513
           driver-class-name: com.mysql.cj.jdbc.Driver
         datax: # 第三个数据源
-          url: jdbc:mysql://127.0.0.1:3306/datax_web?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+          url: jdbc:mysql://127.0.0.1:3306/datax_web?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
           username: root
           password: Xinxi513513
           driver-class-name: com.mysql.cj.jdbc.Driver

+ 3 - 2
module_kzks/src/main/java/org/jeecg/modules/projectImportList/controller/ProjectImportListController.java

@@ -118,8 +118,9 @@ public class ProjectImportListController extends JeecgController<ProjectImportLi
             return kpiImportListService.importExcel1(url, KpiImportList.class);
         } else if (projectImportList.getFileType().equals("9")) { //导入数据包至服务器
             return result.success("");
-        } else if (projectImportList.getFileType().equals("10")){
-            return wzOutboundOrderBNewService.importExcel1(url, WzOutboundOrderBNew.class);
+        } else if (projectImportList.getFileType().equals("10")){//物资导入
+//            return wzOutboundOrderBNewService.importExcel1(url, WzOutboundOrderBNew.class);
+            return wzOutboundOrderBNewService.importExcelNew(url, WzOutboundOrderBNew.class);
         } else {
             result.setCode(500);
             result.setMessage("请选择正确的导入类型!");

+ 22 - 5
module_kzks/src/main/java/org/jeecg/modules/wzOutboundOrderBNew/entity/WzOutboundOrderBNew.java

@@ -2,8 +2,17 @@ package org.jeecg.modules.wzOutboundOrderBNew.entity;
 
 import java.io.Serializable;
 import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Type;
 import java.util.Date;
 import java.math.BigDecimal;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.converters.bigdecimal.BigDecimalNumberConverter;
+import com.alibaba.excel.converters.bigdecimal.BigDecimalStringConverter;
+import com.alibaba.excel.converters.date.DateDateConverter;
+import com.alibaba.excel.converters.date.DateNumberConverter;
+import com.alibaba.excel.converters.date.DateStringConverter;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -26,7 +35,7 @@ import lombok.experimental.Accessors;
  */
 @Data
 @TableName("wz_outbound_order_b_new")
-@Accessors(chain = true)
+@Accessors(chain = false)
 @EqualsAndHashCode(callSuper = false)
 @ApiModel(value="wz_outbound_order_b_new对象", description="wz_outbound_order_b_new")
 public class WzOutboundOrderBNew implements Serializable {
@@ -34,6 +43,7 @@ public class WzOutboundOrderBNew implements Serializable {
 
 	/**id*/
 	@TableId(type = IdType.ASSIGN_ID)
+    @ExcelIgnore
     @ApiModelProperty(value = "id")
     private java.lang.String id;
 	/**来源(日期)*/
@@ -122,16 +132,19 @@ public class WzOutboundOrderBNew implements Serializable {
     private java.lang.String sccs;
 	/**应发数量*/
 	@Excel(name = "应发数量", width = 15)
+    @ExcelProperty(converter = BigDecimalNumberConverter.class)
     @ApiModelProperty(value = "应发数量")
     private java.math.BigDecimal yfsl;
 	/**实发数量*/
 	@Excel(name = "实发数量", width = 15)
+    @ExcelProperty(converter = BigDecimalNumberConverter.class)
     @ApiModelProperty(value = "实发数量")
     private java.math.BigDecimal sfsl;
 	/**质保有效期*/
-	@Excel(name = "质保有效期", width = 15, format = "yyyy-MM-dd")
-	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
-    @DateTimeFormat(pattern="yyyy-MM-dd")
+//	@Excel(name = "质保有效期", width = 15, format = "yyyy-MM-dd HH:mm:ss")
+    @ExcelProperty(value = "质保有效期", converter = DateStringConverter.class)
+	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
     @ApiModelProperty(value = "质保有效期")
     private java.util.Date zbyxq;
 	/**质保单位*/
@@ -200,14 +213,17 @@ public class WzOutboundOrderBNew implements Serializable {
     private java.lang.String nzyj;
 	/**单价*/
 	@Excel(name = "单价", width = 15)
+    @ExcelProperty(converter = BigDecimalStringConverter.class)
     @ApiModelProperty(value = "单价")
     private java.math.BigDecimal nbdj;
 	/**采购单价*/
 	@Excel(name = "采购单价", width = 15)
+    @ExcelProperty(converter = BigDecimalStringConverter.class)
     @ApiModelProperty(value = "采购单价")
     private java.math.BigDecimal cgdj;
 	/**金额*/
 	@Excel(name = "金额", width = 15)
+    @ExcelProperty(converter = BigDecimalNumberConverter.class)
     @ApiModelProperty(value = "金额")
     private java.math.BigDecimal je;
 	/**储位号*/
@@ -239,7 +255,8 @@ public class WzOutboundOrderBNew implements Serializable {
     @ApiModelProperty(value = "批次号")
     private java.lang.String pch;
 	/**首次入库时间*/
-	@Excel(name = "首次入库时间", width = 15, format = "yyyy-MM-dd")
+//	@Excel(name = "首次入库时间", width = 15, format = "yyyy-MM-dd")
+    @ExcelProperty(value = "首次入库时间", converter = DateStringConverter.class)
 	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
     @DateTimeFormat(pattern="yyyy-MM-dd")
     @ApiModelProperty(value = "首次入库时间")

+ 65 - 0
module_kzks/src/main/java/org/jeecg/modules/wzOutboundOrderBNew/monitor/WzOutboundOrderBNewListerner.java

@@ -0,0 +1,65 @@
+package org.jeecg.modules.wzOutboundOrderBNew.monitor;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import lombok.extern.slf4j.Slf4j;
+import org.checkerframework.checker.index.qual.SameLen;
+import org.jeecg.modules.wzOutboundOrderBNew.entity.WzOutboundOrderBNew;
+import org.jeecg.modules.wzOutboundOrderBNew.mapper.WzOutboundOrderBNewMapper;
+import org.jeecg.modules.wzOutboundOrderBNew.service.IWzOutboundOrderBNewService;
+
+import java.nio.file.LinkOption;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * ClassName: WzOutboundOrderBNewListerner
+ * Package: org.jeecg.modules.wzOutboundOrderBNew.monitor
+ * Description:   监听器
+ *
+ * @Author sl
+ * @Create 2024/3/26 11:28
+ * @Version 1.0
+ */
+@Slf4j
+public class WzOutboundOrderBNewListerner extends AnalysisEventListener<WzOutboundOrderBNew> {
+    private IWzOutboundOrderBNewService wzOutboundOrderBNewService;
+    //每隔1000条存储数据库,实际使用中可以3000条,然后清理list,方便内存回收
+    private static final int BATCH_COUNT = 3000;
+    List<WzOutboundOrderBNew> list = new ArrayList<>();
+
+    public WzOutboundOrderBNewListerner() {
+    }
+
+    public WzOutboundOrderBNewListerner(IWzOutboundOrderBNewService wzOutboundOrderBNewService) {
+        this.wzOutboundOrderBNewService = wzOutboundOrderBNewService;
+    }
+
+    @Override
+    public void invoke(WzOutboundOrderBNew wzOutboundOrderBNew, AnalysisContext analysisContext){
+//        System.out.println(wzOutboundOrderBNew);
+        list.add(wzOutboundOrderBNew);
+//        System.out.println(list);
+        //达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
+        if(list.size() >= BATCH_COUNT){
+            saveData();
+            //存储完成清理list
+            list.clear();
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext){
+        //这里也要保存数据,确保最后遗留的数据也存储到数据库
+        saveData();
+        log.info("所有数据解析完成!");
+    }
+
+    //存储数据库
+    private void saveData(){
+        log.info("{}条数据,开始存储数据库!", list.size());
+        wzOutboundOrderBNewService.saveBatch(list);
+        log.info("数据存储数据库成功!");
+    }
+
+}

+ 1 - 0
module_kzks/src/main/java/org/jeecg/modules/wzOutboundOrderBNew/service/IWzOutboundOrderBNewService.java

@@ -13,5 +13,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
 public interface IWzOutboundOrderBNewService extends IService<WzOutboundOrderBNew> {
 
     Result<?> importExcel1(String strUrl, Class<WzOutboundOrderBNew> clazz);
+    Result<?> importExcelNew(String strUrl, Class<WzOutboundOrderBNew> clazz);
 
 }

+ 40 - 4
module_kzks/src/main/java/org/jeecg/modules/wzOutboundOrderBNew/service/impl/WzOutboundOrderBNewServiceImpl.java

@@ -1,5 +1,9 @@
 package org.jeecg.modules.wzOutboundOrderBNew.service.impl;
 
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.EasyExcelFactory;
+import com.alibaba.excel.ExcelReader;
+import com.alibaba.excel.read.metadata.ReadSheet;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
@@ -8,6 +12,7 @@ import org.jeecg.common.util.DateUtils;
 import org.jeecg.modules.projectKmbh.entity.KzksProjectKmbh;
 import org.jeecg.modules.wzOutboundOrderBNew.entity.WzOutboundOrderBNew;
 import org.jeecg.modules.wzOutboundOrderBNew.mapper.WzOutboundOrderBNewMapper;
+import org.jeecg.modules.wzOutboundOrderBNew.monitor.WzOutboundOrderBNewListerner;
 import org.jeecg.modules.wzOutboundOrderBNew.service.IWzOutboundOrderBNewService;
 import org.jeecgframework.poi.excel.ExcelImportUtil;
 import org.jeecgframework.poi.excel.entity.ImportParams;
@@ -16,10 +21,7 @@ import org.springframework.stereotype.Service;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -79,4 +81,38 @@ public class WzOutboundOrderBNewServiceImpl extends ServiceImpl<WzOutboundOrderB
             }
         }
     }
+
+
+    @Override
+    public Result<?> importExcelNew(String strUrl, Class<WzOutboundOrderBNew> clazz) {
+//        InputStream inputStream = null;
+//        try {
+//            inputStream = new FileInputStream(strUrl);
+//        } catch (FileNotFoundException e) {
+//            e.printStackTrace();
+//        }
+//        EasyExcel.read(inputStream, clazz , new WzOutboundOrderBNewListerner())
+//                .sheet(0)//指定读取哪个sheet
+//                .headRowNumber(2)//指定标题行(需要)
+//                .doRead();//执行读取
+
+//        EasyExcel.read(strUrl, clazz, new WzOutboundOrderBNewListerner(this)).sheet().doRead();
+
+//        InputStream in = null;
+//        try {
+//            in = new BufferedInputStream(new FileInputStream(strUrl));
+//        } catch (FileNotFoundException e) {
+//            e.printStackTrace();
+//        }
+
+        int year = DateUtils.getYear();
+        orderBNewMapper.deleteByDate(year);
+
+        ExcelReader excelReader = EasyExcel.read(new File(strUrl), clazz, new WzOutboundOrderBNewListerner(this)).build();
+        ReadSheet readSheet = EasyExcel.readSheet(0).build();
+        excelReader.read(readSheet);
+        //这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
+        excelReader.finish();
+        return Result.ok("文件导入成功!");
+    }
 }