easypoi 结合mybatis-plus导入大批量数据

背景:spring boot+mybatis-plus项目需要通过接口导入50W数据。

excel解析,通过easypoi进行实体类映射。

Excel解析实体类:

@Data
public class ForecastUserImpExcel implements Serializable {
    private Long id;

    @Excel(name = "序号")
    private String sequenceNum;

    @Excel(name = "零售用户名称")
    private String clientName;

    @Excel(name = "户号")
    private String clientCode;

    @Excel(name = "日期",format = "yyyy-MM-dd")
    private Date generateDate;

    @Excel(name = "电能表id")
    private String electricityMeter;

    @Excel(name = "电能表冻结数值")
    private BigDecimal electricityVal;

    @Excel(name = "倍率")
    private BigDecimal times;

    @Excel(name = "是否参考表")
    private String isReference;

    private String year;

    private String month;

}

entity代码:

package com.siact.module.forecast.entity;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;

import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 预测用户导入数据
 *
 * @author xiela xiela@163.com
 * @since v1.0.0 2021-01-06
 */
@Data
@EqualsAndHashCode(callSuper=false)
@TableName("forecast_user_imp")
public class ForecastUserImpEntity {
	private static final long serialVersionUID = 1L;

    /**
     * id
     */
	private Long id;
    /**
     * 序号
     */
	private String sequenceNum;
    /**
     * 零售用户名称
     */
	private String clientName;
    /**
     * 户号
     */
	private String clientCode;
    /**
     * 日期
     */
	private Date generateDate;
    /**
     * 电表id
     */
	private String electricityMeter;
    /**
     * 电能表冻结数值
     */
	private BigDecimal electricityVal;
    /**
     * 倍数
     */
	private BigDecimal times;
    /**
     * 是否参考表
     */
	private String isReference;
    /**
     * 年度
     */
	private String year;
    /**
     * 月份
     */
	private String month;
}

controller代码:

   @Autowired
    private ForecastUserImpService forecastUserImpService;

    @PostMapping("import")
    public Result importExcel(@RequestParam String year, @RequestParam String month, MultipartFile file) {
        return forecastUserImpService.importExcel(year, month, file);
    }

service代码:

/**
  * forecast_user_imp 模板表名称,根据年度和月份动态拼接表名
  */
public Result importExcel(String year, String month, MultipartFile file) {
        //动态创建表
        baseDao.createTable("forecast_user_imp_" + year + "_" + month);
        long start = System.currentTimeMillis();
        try {
            ExcelUtils.importExcelBySax(file.getInputStream(), 0, 1,
            ForecastUserImpExcel.class,
            new IReadHandler<ForecastUserImpExcel> (){
                List<ForecastUserImpExcel> excelDtos = new ArrayList<>();
                @Override
                public void handler(ForecastUserImpExcel o) {
                    o.setYear(year);
                    o.setMonth(month);
                    excelDtos.add(o);
                    if(excelDtos.size() == 10000){
                        List<ForecastUserImpExcel> userImpExcels = deepCopy(excelDtos);
                        Thread thread = new Thread(() -> {
                            List<ForecastUserImpEntity> userImpDTOS = ConvertUtils.sourceToTarget(userImpExcels, ForecastUserImpEntity.class);
                            baseDao.insertCustomerMachineByBatch(userImpDTOS,"forecast_user_imp_" + year + "_" + month);
                        });
                        thread.start();
                        excelDtos = new ArrayList<>();
                    }
                }
                @Override
                public void doAfterAll() {
                    if(excelDtos.size() > 0){
                        List<ForecastUserImpExcel> userImpExcels = deepCopy(excelDtos);
                        Thread thread = new Thread(() -> {
                            List<ForecastUserImpEntity> userImpDTOS = ConvertUtils.sourceToTarget(userImpExcels, ForecastUserImpEntity.class);
                            baseDao.insertCustomerMachineByBatch(userImpDTOS,"forecast_user_imp_" + year + "_" + month);
                        });
                        thread.start();
                        excelDtos = new ArrayList<>();
                    }
                }
            });

        } catch (IOException e) {
            return new Result<>().error("导入错误!");
        }
        return new Result<>();
    }


    /**
     * list 深拷贝
     * @param srcList
     * @param <T>
     * @return
     */
    public static <T> List<T> deepCopy(List<T> srcList){
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        try {
            ObjectOutputStream out = new ObjectOutputStream(byteOut);
            out.writeObject(srcList);
            ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
            ObjectInputStream inStream = new ObjectInputStream(byteIn);
            List<T> destList = (List<T>) inStream.readObject();
            return destList;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

dao代码:

    void createTable(String tableName);

    int insertCustomerMachineByBatch(@Param("list") List<ForecastUserImpEntity> list,@Param("tableName") String tableName);

 

XML代码:

    <update id="createTable">
        create table if not Exists ${tableName} like forecast_user_imp
    </update>


    <insert id="insertCustomerMachineByBatch">
        insert into ${tableName}
            (`sequence_num`,
             `client_name`,
            `client_code`,
            `generate_date`,
            `electricity_meter`,
            `electricity_val`,
            `times`,
            `is_reference`,
            `year`,
            `month`)
        values
        <foreach collection="list" separator="," item="i">
            (
            #{i.sequenceNum},
            #{i.clientName},
            #{i.clientCode},
            #{i.generateDate},
            #{i.electricityMeter},
            #{i.electricityVal},
            #{i.times},
            #{i.isReference},
            #{i.year},
            #{i.month}
            )
        </foreach>
    </insert>

注意事项:

1.只支持xlsx格式的excel;

2.需要引入SAX的解析包;       
         <dependency>
            <groupId>xerces</groupId>
            <artifactId>xercesImpl</artifactId>
            <version>2.9.0</version>
        </dependency>
3.实体类的fixedIndex注解不能使用

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值