使用到了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;
}
}