关于使用easyExcel读取前端文件和MybatisPlus批量插入

关于使用easyExceld读取前端文件和MybatisPlus批量插入

最近写项目,后端需要用到easyExcel来获取前端上传的表格,分析表格数据并存储到数据库

项目暂时是:springBoot + MybatisPlus

easyExcel官方文档地址:读Excel | Easy Excel (alibaba.com)

因为项目中我暂时只用到读Excel,所以文档的地址就给大家放到上面啦,有其他需要的话可以自查

实体类

第一步,你需要一个实体类,这个实体类对应数据库中的一个表

然后使用@ExcelProperty注解将excel表的列名对应的属性绑定起来

比如:我的Excel表是这样的:
在这里插入图片描述

那么绑定到实体类就应该是这样的:

@Data
public class Classroom implements Serializable {
    //自增
    private int classroomId;
    @ExcelProperty("教室号")
    private String classroomName;
    //管理员的buildingId
    private int buildingId;
    @ExcelProperty("摄像头设备id")
    private String cameraId;
    @ExcelProperty("esp8266id")
    private String espId;
    @ExcelProperty("可通电的最少人数")
    private int numLimitOn;
    @ExcelProperty("教室分流人数阈值")
    private int numPeakFlow;
    @ExcelProperty("可通电的最低温度")
    private float temperatureLimitOn;
    @ExcelProperty("断电最高温度阈值")
    private float temperatureLimitOff;
    @ExcelProperty("教室容量")
    private int classroomCapacity;
    @ExcelProperty("是否特殊供电")
    private int specialOn;
}

监听器

第二步,按照官方文档,还需要一个监听器

//官方文档中又有比较详细的注释,我的代码因为要实现自己的需求,所以和官方文档可能不太一样
//这里我就挑一些可能比较重要的部分写上注释
@Data
@Component   //加上Component注解的同时记得到启动类上使用@MapperScan加上这个类的包路径,不然扫描不到会报空指针异常
public class ClassroomListener extends AnalysisEventListener<Classroom> {
	
    private static final int BATCH_COUNT = 10000;
    private static List<Classroom> cachedDataList = new ArrayList<>();
    private int buildingId;
    
    @Resource
    private ClassroomMapper classroomMapper;

    //这是一个回调函数,就是每读取一条数据都会来执行这个方法
    @Override
    public void invoke(Classroom classroom, AnalysisContext analysisContext) {

        classroom.setBuildingId(buildingId);
        //每次读取excel表中的一条数据,都存放到list中
        cachedDataList.add(classroom);
        //直到超过10000条,就进行持久化操作,然后清空ilst集合,继续读取
        if(cachedDataList.size() >= BATCH_COUNT){
            saveData();
            cachedDataList.clear();
        }
    }

    //这个函数是只有在读取完所有数据之后,才会调用(只执行一次)
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveData();
        cachedDataList.clear();
    }

    //这里是持久化操作,因为不想多次调用insert,所以我选择批量插入
    //insertBatchSomeColumn:这个批量插入还需要做其他的配置,放在后面将
    private void saveData() {
        //批量插入
        classroomMapper.insertBatchSomeColumn(cachedDataList);
    }
}

开始调用

到这一步就可以开始通过这个监听器来读写excel了

//注入listener
@Resource
ClassroomListener classroomListener;

pubilc void test(){
    //是的,在你的业务层调用easyExcel读写excel的时候只需要这一行代码就够了
    //你可以配合上你自己的代码逻辑去使用
     EasyExcel.read(multipartFile.getInputStream(), Classroom.class, classroomListener)
         	  .sheet().doRead();
}

可能出现的问题

如果有仔细看easyExcel官方文档中的代码的同学可能就会,发现,我的代码和官方的其实还是有细微的差别

区别就在于,我通过@Compotent注解手动的将Listener作为一个普通组件交给Spring,从而做到可以在Listener中注入Mapper

而官方文档中的是没有将他交给Spring的,而且在测试的时候,官方代码如下:

 EasyExcel.read(multipartFile.getInputStream(), Classroom.class, new ClassroomListener()).sheet().doRead();

仔细看,可以发现官方文档在业务层的代码中的Listen是直接通过new新建出来的

而我的是则是直接在业务层注入Listen这个Bean(上面有提到我给Listener加了@Component注解,已经把他交给Spring了)

因为事实上,监听器,过滤器,以及拦截器都是不归Spring管的

所以如果你不将监听器手动交给Spring的,直接在监听器中使用@Resource注解的话,就会报空指针异常,因为这个时候注入是无效的

感兴趣的可以上网搜一下:”监听器中@Resource注解和@Autowire注解失效“

当然,解决这个问题也不止可以用注解,也可以自己写工具类,提供一些其他的方法去拿到Bean

最后,关于MybatisPlus的批量插入

MybatisPlus其实也有提供一个批量插入的方法,但是那个方式本质上也是多次的调用insert()

关于insertBatchSomeColumn(List list)这个方法,大家可以直接复制下面的代码就可以了

写一个工具类

package com.airweb.util;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
import java.util.List;

public class InsertBatchSqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
        methodList.add(new InsertBatchSomeColumn());
        return methodList;
    }
}

写一个配置类

package com.airweb.config;
import com.airweb.util.InsertBatchSqlInjector;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class MybatisPlusConfig {

    @Bean
    public InsertBatchSqlInjector easySqlInjector () {
        return new InsertBatchSqlInjector();
    }
}

到Mappe中添加这个方法

package com.airweb.mapper;
import com.airweb.model.entity.Building;
import com.airweb.model.entity.Classroom;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;

@Mapper
public interface ClassroomMapper extends BaseMapper<Classroom> {

    /**
     * 批量插入
     * @param classrooms
     */
    void insertBatchSomeColumn(@Param("list") List<Classroom> classrooms);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值