自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

SpringBoot+Mybatis-plus整合EasyExcel批量導(dǎo)入Excel到數(shù)據(jù)庫+導(dǎo)出Excel

數(shù)據(jù)庫 其他數(shù)據(jù)庫
今天小編帶大家一起整合一下EasyExcel,之所以用這個,是因為EasyExcel性能比較好,不會報OOM!

一、前言

今天小編帶大家一起整合一下easyExcel?,之所以用這個,是因為easyExcel?性能比較好,不會報OOM!

市面上常見的導(dǎo)入導(dǎo)出Excel分為三種:

  • hutool
  • easyExcel
  • poi

hutool和easyExcel?都是對poi?的封裝,使用起來更加方便!

二、導(dǎo)入依賴

小編這里是3.0.X版本的,版本不同可能導(dǎo)致部分有出入,如果大家版本是3.1.X,可以去官方文檔看看有不一樣的!

官方文檔:https://easyexcel.opensource.alibaba.com/

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>

三、實體類

這里可以自帶的轉(zhuǎn)換器:

  • @DateTimeFormat("yyyy年MM月dd日HH時mm分ss秒")
  • LocalDateTimeStringConverter

或者自定義轉(zhuǎn)化器:實現(xiàn):implements Converter<T>。

具體文檔:官方文檔:https://easyexcel.opensource.alibaba.com/docs/3.0.x/quickstart/read#%E6%97%A5%E6%9C%9F%E6%95%B0%E5%AD%97%E6%88%96%E8%80%85%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%BC%E5%BC%8F%E8%BD%AC%E6%8D%A2

@ExcelProperty參數(shù)注意:

這里不建議 index 和 name 同時用,要么一個對象只用index,要么一個對象只用name去匹配。

用名字去匹配,這里需要注意,如果名字重復(fù),會導(dǎo)致只有一個字段讀取到數(shù)據(jù)。

/**
* @author wangzhenjun
* @date 2022/12/2 15:52
*/
@Data
public class Test {

@TableId
private Integer id;
@ExcelProperty(index = 0)
private String name;
@ExcelProperty(index = 1)
private Integer age;
@ExcelProperty(index = 2,converter = LocalDateTimeStringConverter.class)
private LocalDateTime time;
}

四、編寫監(jiān)聽器

注意點(diǎn):這個監(jiān)聽器一定不要是單例的,被spring管理默認(rèn)為單例,如果要使用?@Component?,一定要加上:@Scope("prototype")?,這樣在創(chuàng)建完后spring不會進(jìn)行管理,每次都會是新bean!不加?@Component?在導(dǎo)入時要進(jìn)行new ImportDataListener!小編這里不想new了直接這樣寫??!如果不想這樣,可以使用構(gòu)造器set進(jìn)行使用!BATCH_COUNT?:數(shù)據(jù)閾值,超過了就會清理list,在之前可以進(jìn)行保存到數(shù)據(jù)庫中,方便內(nèi)存回收,防治OOM!這里保存到數(shù)據(jù)庫中一般使用?批量保存,不要解析到一行就去保存數(shù)據(jù)庫中,這樣數(shù)據(jù)量大會給數(shù)據(jù)庫增加IO,導(dǎo)致掛掉!這里小編使用ServiceImpl的saveBatch()方法,也可以自己寫一下,像小編這樣寫,會出現(xiàn)循環(huán)依賴,加上@Lazy就行!

/**
* @author wangzhenjun
* @date 2022/12/2 15:38
*/
@Slf4j
@Component
// 每次bean都是新的,不要單例
@Scope("prototype")
public class ImportDataListener implements ReadListener<Test> {

@Autowired
@Lazy
private TestService testService;

/**
* 每隔5條存儲數(shù)據(jù)庫,實際使用中可以100條,然后清理list ,方便內(nèi)存回收
*/
private static final int BATCH_COUNT = 100;
/**
* 緩存的數(shù)據(jù)
*/
private List<Test> importExcelDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);


/**
* 這個每一條數(shù)據(jù)解析都會來調(diào)用
*
* @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context
*/
@Override
public void invoke(Test data, AnalysisContext context) {
log.info("解析到一條數(shù)據(jù):{}", JSON.toJSONString(data));
importExcelDataList.add(data);
// 達(dá)到BATCH_COUNT了,需要去存儲一次數(shù)據(jù)庫,防止數(shù)據(jù)幾萬條數(shù)據(jù)在內(nèi)存,容易OOM
if (importExcelDataList.size() >= BATCH_COUNT) {
saveData();
// 存儲完成清理 list
importExcelDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
}
}

/**
* 所有數(shù)據(jù)解析完成了 都會來調(diào)用
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 這里也要保存數(shù)據(jù),確保最后遺留的數(shù)據(jù)也存儲到數(shù)據(jù)庫
saveData();
log.info("所有數(shù)據(jù)解析完成!");
}

/**
* 加上存儲數(shù)據(jù)庫
*/
private void saveData() {
log.info("{}條數(shù)據(jù),開始存儲數(shù)據(jù)庫!", importExcelDataList.size());
testService.saveBatch(importExcelDataList);
log.info("存儲數(shù)據(jù)庫成功!");
}
}

五、Controller

/**
* @author wangzhenjun
* @date 2022/10/26 16:51
*/
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {

@Autowired
private TestService testService;

@PostMapping("/import")
public Result importExcel(@RequestBody MultipartFile multipartFile){
testService.importExcel(multipartFile);
return Result.success("ok");
}
}

六、Service

/**
* @author wangzhenjun
* @date 2022/10/26 16:55
*/
public interface TestService extends IService<Test> {
void importExcel(MultipartFile multipartFile);
}

七、ServiceImpl

/**
* @author wangzhenjun
* @date 2022/10/26 16:56
*/
@Service
public class TestServiceImpl extends ServiceImpl<TestDbMapper, Test> implements TestService{

@Autowired
private ImportDataListener importDataListener;

@SneakyThrows
@Override
public void importExcel(MultipartFile multipartFile) {
InputStream inputStream = multipartFile.getInputStream();
// 這里 需要指定讀用哪個class去讀,然后讀取第一個sheet 文件流會自動關(guān)閉
EasyExcel.read(inputStream, Test.class, importDataListener).sheet().doRead();
}
}

八、Mapper

/**
* @author wangzhenjun
* @date 2022/10/26 17:07
*/
public interface TestDbMapper extends BaseMapper<Test> {
}

九、測試

準(zhǔn)備Excel數(shù)據(jù):

圖片

postman上傳:

圖片

控制臺打印:

圖片

數(shù)據(jù)庫查看:

圖片

完美搞定??!

十、總結(jié)

這樣就完成了easyExcel批量導(dǎo)入Excel到數(shù)據(jù)庫,還是有很多要注意的點(diǎn):

  • 自定義轉(zhuǎn)換器
  • 監(jiān)聽器不要單例
  • 保存數(shù)據(jù)庫采用批量
  • 版本差距
責(zé)任編輯:姜華 來源: 小王博客基地
相關(guān)推薦

2010-07-21 14:17:36

SQL Server數(shù)

2011-03-10 10:50:01

excelsql數(shù)據(jù)庫

2010-04-22 11:58:00

Oracle數(shù)據(jù)庫

2022-09-29 10:06:56

SQLMySQL服務(wù)端

2023-06-07 08:08:37

MybatisSpringBoot

2024-04-09 13:20:00

Excel數(shù)據(jù)庫數(shù)據(jù)

2020-12-18 10:40:00

ExcelJava代碼

2023-09-20 10:04:04

Python工具

2022-05-11 09:02:27

Python數(shù)據(jù)庫Excel

2011-03-24 16:46:44

微軟Excel數(shù)據(jù)庫

2021-11-04 10:45:46

SpringBootExcelJava

2021-09-27 07:56:41

MyBatis Plu數(shù)據(jù)庫批量插入

2009-07-28 11:00:24

Excel導(dǎo)入SQL

2010-04-14 09:24:29

在Oracle數(shù)據(jù)庫

2011-03-01 14:52:31

EXCEL財務(wù)分析?數(shù)據(jù)庫

2009-08-11 14:51:47

C#讀取Excel中數(shù)

2011-04-13 09:03:58

Oracle數(shù)據(jù)庫導(dǎo)入導(dǎo)出

2011-03-17 13:23:08

數(shù)據(jù)導(dǎo)入導(dǎo)出

2011-04-15 10:37:53

Oracle導(dǎo)入導(dǎo)出語法

2010-11-09 17:19:49

SQL Server導(dǎo)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號