使用EasyExcel导入表格来进行批量插入数据----后端实现

使用到了MapStruct和阿里的EasyExcel。

1.创建一个实体类对应表格中的字段:

@Data
@EqualsAndHashCode
public class RepositoryExcel {

    private Long safeTypeId;

    private Integer quesType;

    private String quesContent;

    private String options;

    private String answer;

}

2.创建数据监听器:
注意:需要使用set方法把Spring管理的类来传进来,否则在数据插入时会报空指针异常。

@Slf4j
public class RepositoryDataListen implements ReadListener<RepositoryExcel> {
    /**
     * 每隔1条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 1;
    /**
     * 缓存的数据
     */
    private List<RepositoryExcel> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
    /**
     * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
     */
    private IERepositoryService repositoryService;


    /**
     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     *
     * @param
     */
    public RepositoryDataListen(IERepositoryService repositoryService) {
        this.repositoryService=repositoryService;
    }

    @Override
    public void invoke(RepositoryExcel data, AnalysisContext analysisContext) {
        log.info("解析到一条数据:{}", JSON.toJSONString(data));
        cachedDataList.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveData();
        log.info("所有数据解析完成!");
    }
    private void saveData(){
        log.info("{}条数据,开始存储数据库",cachedDataList.size());
        System.out.println(cachedDataList.toString());
        repositoryService.saveRepository(cachedDataList);
        log.info("存储数据库成功!");
    }
}

3.service层:

接口:

 void saveRepository(List<RepositoryExcel> cachedDataList);

实现类:

 @Override
    public void saveRepository(List<RepositoryExcel> cachedDataList) {
        System.out.println("插入的学生数据"+cachedDataList);
        eRepositoryMapper.save(cachedDataList);

    }

4.mapper层:
我这里写的是一个一个的插入,但是最好写一个批量插入的方法。

 @Insert(
            ""
    )
    void save(@Param("list") List<RepositoryExcel> cachedDataList);

5.controller层:

 	@ApiOperation("导入文件")
    @PostMapping("/import")
    @ResponseBody
    public Result<Object> importFile(@RequestPart MultipartFile file) throws IOException {
        EasyExcel.read(file.getInputStream(), RepositoryExcel.class,new RepositoryDataListen(eRepositoryService)).sheet().doRead();
        return Result.success();
    }

第二种方法:不使用手写的sql语句(改良版)
在service实现类中:

	private final RepositoryMapStruct repositoryMapStruct;

	@Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRepository(List<RepositoryExcel> cachedDataList) {
        List<ERepository> excel = repositoryMapStruct.excel(cachedDataList);
        for (ERepository eRepository : excel){
            this.save(eRepository);
        }
    }

创建一个RepositoryMapStruct 接口:

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface RepositoryMapStruct {
    ERepository toRepositoryDto(ERepositoryDto repository);

    List<ERepository> excel(List<RepositoryExcel> cachedDataList);
}

在RepositoryMapStruct 实现类中:
(实现类是自动生成的)

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2022-04-21T17:44:54+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_121 (Oracle Corporation)"
)
@Component
public class RepositoryMapStructImpl implements RepositoryMapStruct {
	 @Override
    public ERepository toRepositoryDto(ERepositoryDto repository) {
        if ( repository == null ) {
            return null;
        }

        ERepository eRepository = new ERepository();

        eRepository.setCreateBy( repository.getCreateBy() );
        eRepository.setUpdateBy( repository.getUpdateBy() );
        eRepository.setCreateTime( repository.getCreateTime() );
        eRepository.setUpdateTime( repository.getUpdateTime() );
        eRepository.setDeleted( repository.getDeleted() );
        eRepository.setId( repository.getId() );
        eRepository.setSafeTypeId( repository.getSafeTypeId() );
        eRepository.setQuesType( repository.getQuesType() );
        eRepository.setQuesContent( repository.getQuesContent() );
        eRepository.setOptions( repository.getOptions() );
        eRepository.setAnswer( repository.getAnswer() );
        eRepository.setIsCheck( repository.getIsCheck() );

        return eRepository;
    }

    @Override
    public List<ERepository> excel(List<RepositoryExcel> cachedDataList) {
        if ( cachedDataList == null ) {
            return null;
        }

        List<ERepository> list = new ArrayList<ERepository>( cachedDataList.size() );
        for ( RepositoryExcel repositoryExcel : cachedDataList ) {
            list.add( repositoryExcelToERepository( repositoryExcel ) );
        }

        return list;
    }

    protected ERepository repositoryExcelToERepository(RepositoryExcel repositoryExcel) {
        if ( repositoryExcel == null ) {
            return null;
        }

        ERepository eRepository = new ERepository();

        eRepository.setSafeTypeId( repositoryExcel.getSafeTypeId() );
        eRepository.setQuesType( repositoryExcel.getQuesType() );
        eRepository.setQuesContent( repositoryExcel.getQuesContent() );
        eRepository.setOptions( repositoryExcel.getOptions() );
        eRepository.setAnswer( repositoryExcel.getAnswer() );

        return eRepository;
    }
}

你可能感兴趣的:(springBoot,EasyExcel,后端)