最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MybatisPlus實現(xiàn)真正批量插入的詳細(xì)步驟

 更新時間:2024年10月08日 10:10:23   作者:總是學(xué)不會.  
在數(shù)據(jù)庫操作中,批量插入是提升效率的重要手段,MyBatis-Plus提供了多種批量插入方法,但默認(rèn)的saveBatch方法效率并不高,文章介紹了通過手動拼接SQL、使用IService接口以及自定義insertBatchSomeColumn方法進(jìn)行優(yōu)化,以實現(xiàn)更高效的批量插入,并給出了性能優(yōu)化建議

在實際開發(fā)中,批量插入是提高數(shù)據(jù)處理效率的常用手段。MyBatis-Plus 作為 MyBatis 的增強(qiáng)工具,提供了多種方式來實現(xiàn)批量插入。然而,默認(rèn)的 saveBatch 方法在底層實際上是逐條插入,性能上并不理想。本文將詳細(xì)介紹如何通過 MyBatis-Plus 實現(xiàn)真正高效的批量插入,包括手動拼接 SQL、使用 IService 接口以及自定義 insertBatchSomeColumn 方法,并提供性能優(yōu)化建議。

一、通過 XML 手動拼接 SQL 實現(xiàn)批量插入

優(yōu)勢

  • 高效:一次性執(zhí)行批量插入,減少數(shù)據(jù)庫交互次數(shù)。
  • 靈活:可以根據(jù)需要選擇性插入部分字段,減少不必要的數(shù)據(jù)傳輸。

缺點

  • 維護(hù)成本高:每個表都需要手動編寫對應(yīng)的 XML SQL。
  • 不支持自動生成主鍵:如果表中有自增主鍵,需額外處理。

實現(xiàn)步驟

編寫 Mapper XML 文件

history_summary 表為例,編寫批量插入的 XML:

<insert id="insertBatch" parameterType="java.util.List">
    INSERT INTO history_summary
    (key_id, business_no, status, customer_id, instruction_id, customer_business_no, dept_id, doc_type_id, doc_page_no, document_version, result_mongo_doc_id, is_active, problem_status, tran_source, document_count_page, is_rush, is_deleted, document_tran_time, customer_tran_time, preprocess_recv_time, delete_time, create_time, complete_time, version, zip_name, document_no, new_task_type, handle_begin_time, handle_end_time, cost_seconds, char_num, ocr_result_mongo_id, reserve_text2, reserve_text3, reserve_text1, reserve_text4, reserve_text5, ocr_result_type, repeat_status, form_version, repetition_count)
    VALUES
    <foreach collection="list" item="item" separator=",">
        (#{item.keyId}, #{item.businessNo}, #{item.status}, #{item.customerId}, #{item.instructionId}, #{item.customerBusinessNo}, #{item.deptId}, #{item.docTypeId}, #{item.docPageNo}, #{item.documentVersion}, #{item.resultMongoDocId}, #{item.isActive}, #{item.problemStatus}, #{item.tranSource}, #{item.documentCountPage}, #{item.isRush}, #{item.isDeleted}, #{item.documentTranTime}, #{item.customerTranTime}, #{item.preprocessRecvTime}, #{item.deleteTime}, #{item.createTime}, #{item.completeTime}, #{item.version}, #{item.zipName}, #{item.documentNo}, #{item.newTaskType}, #{item.handleBeginTime}, #{item.handleEndTime}, #{item.costSeconds}, #{item.charNum}, #{item.ocrResultMongoId}, #{item.reserveText2}, #{item.reserveText3}, #{item.reserveText1}, #{item.reserveText4}, #{item.reserveText5}, #{item.ocrResultType}, #{item.repeatStatus}, #{item.formVersion}, #{item.repetitionCount})
    </foreach>
</insert>

在 Mapper 接口中定義批量插入方法

public interface historySummaryMapper extends BaseMapper<historySummary> {
    @Insert({
        "<script>",
        "INSERT INTO history_summary ",
        "(key_id, business_no, status, customer_id, instruction_id, customer_business_no, dept_id, doc_type_id, doc_page_no, document_version, result_mongo_doc_id, is_active, problem_status, tran_source, document_count_page, is_rush, is_deleted, document_tran_time, customer_tran_time, preprocess_recv_time, delete_time, create_time, complete_time, version, zip_name, document_no, new_task_type, handle_begin_time, handle_end_time, cost_seconds, char_num, ocr_result_mongo_id, reserve_text2, reserve_text3, reserve_text1, reserve_text4, reserve_text5, ocr_result_type, repeat_status, form_version, repetition_count)",
        "VALUES ",
        "<foreach collection='list' item='item' index='index' separator=','>",
        "(#{item.keyId}, #{item.businessNo}, #{item.status}, #{item.customerId}, #{item.instructionId}, #{item.customerBusinessNo}, #{item.deptId}, #{item.docTypeId}, #{item.docPageNo}, #{item.documentVersion}, #{item.resultMongoDocId}, #{item.isActive}, #{item.problemStatus}, #{item.tranSource}, #{item.documentCountPage}, #{item.isRush}, #{item.isDeleted}, #{item.documentTranTime}, #{item.customerTranTime}, #{item.preprocessRecvTime}, #{item.deleteTime}, #{item.createTime}, #{item.completeTime}, #{item.version}, #{item.zipName}, #{item.documentNo}, #{item.newTaskType}, #{item.handleBeginTime}, #{item.handleEndTime}, #{item.costSeconds}, #{item.charNum}, #{item.ocrResultMongoId}, #{item.reserveText2}, #{item.reserveText3}, #{item.reserveText1}, #{item.reserveText4}, #{item.reserveText5}, #{item.ocrResultType}, #{item.repeatStatus}, #{item.formVersion}, #{item.repetitionCount})",
        "</foreach>",
        "</script>"
    })
    int insertBatch(@Param("list") List<historySummary> list);
}

在 Service 層調(diào)用批量插入方法

@Service
public class historySummaryServiceImpl extends ServiceImpl<historySummaryMapper, historySummary> implements IhistorySummaryService {
    @Autowired
    private historySummaryMapper mapper;
    @Transactional(rollbackFor = Exception.class)
    public boolean batchInsert(List<historySummary> list) {
        int result = mapper.insertBatch(list);
        return result > 0;
    }
}

使用示例

@RestController
@RequestMapping("/api/business")
public class BusinessController {
    @Autowired
    private IhistorySummaryService service;
    @PostMapping("/batchInsert")
    public ResponseEntity<String> batchInsert(@RequestBody List<historySummary> list) {
        boolean success = service.batchInsert(list);
        if (success) {
            return ResponseEntity.ok("批量插入成功");
        } else {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("批量插入失敗");
        }
    }
}

看到這里應(yīng)該頭皮發(fā)麻了吧。這也是我為什么想分享這篇文章的原因?。?!

涉及到多字段批量插入,還是推薦下面的方法。

二、使用 MyBatis-Plus IService 接口的 saveBatch 方法

MyBatis-Plus 提供的 saveBatch 方法簡化了批量插入的操作,但其底層實際上是逐條插入,因此在處理大量數(shù)據(jù)時性能不佳。

優(yōu)勢

  • 簡便易用:無需手動編寫 SQL,直接調(diào)用接口方法即可。
  • 自動事務(wù)管理:內(nèi)置事務(wù)支持,確保數(shù)據(jù)一致性。

缺點

  • 性能有限:底層逐條插入,面對大數(shù)據(jù)量時效率較低。
  • 批量大小受限:默認(rèn)批量大小可能不適用于所有場景,需要手動調(diào)整。

提升性能的方法

配置數(shù)據(jù)庫連接參數(shù)

在數(shù)據(jù)庫的連接 URL 中添加 rewriteBatchedStatements=true,啟用批量重寫功能,提升批量插入性能。

spring.datasource.url=jdbc:mysql://localhost:3306/your_database?rewriteBatchedStatements=true

調(diào)整批量大小

在調(diào)用 saveBatch 方法時,合理設(shè)置批量大小(如 1000 條一批),以平衡性能和資源消耗。

@Transactional(rollbackFor = {Exception.class})
public boolean saveBatch(Collection<T> entityList, int batchSize) {
    String sqlStatement = this.getSqlStatement(SqlMethod.INSERT_ONE);
    return this.executeBatch(entityList, batchSize, (sqlSession, entity) -> {
        sqlSession.insert(sqlStatement, entity);
    });
}

三、insertBatchSomeColumn 方法實現(xiàn)批量插入

為了實現(xiàn)真正高效的批量插入,可以使用 insertBatchSomeColumn 方法,實現(xiàn)一次性批量插入。

優(yōu)勢

  • 高效:一次性執(zhí)行批量插入,減少數(shù)據(jù)庫交互次數(shù)。
  • 靈活:可選擇性插入部分字段,優(yōu)化數(shù)據(jù)傳輸。(通過實體類屬性)

實現(xiàn)步驟

1. 自定義SQL注入器實現(xiàn)DefaultSqlInjector,添加InsertBatchSomeColumn方法

public class MySqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
        methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
        return methodList;
    }
}

2. 將MySqlInjector注入到Bean中

@Configuration
public class MyBatisConfig {
    @Bean
    public MySqlInjector sqlInjector() {
        return new MySqlInjector();
    }
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //添加分頁插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        //添加樂觀鎖插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

3. 繼承Mybatis-plus的BaseMapper,添加插入方法

public interface MyBaseMapper<T> extends BaseMapper<T> {
    int insertBatchSomeColumn(Collection<T> entityList);
}
@Mapper
public interface WorkingBusinessHistoryMapper extends MyBaseMapper<BusinessHistory> {
}

注意事項

  • 批量大小:根據(jù)數(shù)據(jù)庫和應(yīng)用的性能,合理設(shè)置批量插入的大小,避免單次插入過多數(shù)據(jù)導(dǎo)致內(nèi)存溢出或數(shù)據(jù)庫壓力過大。
  • 事務(wù)管理:確保批量操作在事務(wù)中執(zhí)行,以保證數(shù)據(jù)的一致性和完整性。
  • 錯誤處理:在批量操作中,如果某條記錄插入失敗,需要有相應(yīng)的機(jī)制進(jìn)行回滾或記錄失敗信息。

四、性能優(yōu)化建議

為了進(jìn)一步提升批量插入的性能,可以采取以下優(yōu)化措施:

1. 開啟批量重寫功能

在數(shù)據(jù)庫的連接 URL 中添加 rewriteBatchedStatements=true,以優(yōu)化批量插入的性能。

spring.datasource.url=jdbc:mysql://localhost:3306/your_database?rewriteBatchedStatements=true

2. 合理設(shè)置批量大小

根據(jù)具體業(yè)務(wù)場景和數(shù)據(jù)庫性能,調(diào)整批量大?。ㄈ?1000 條一批),避免單次插入過多數(shù)據(jù)。

int batchSize = 1000;
for (int i = 0; i < list.size(); i += batchSize) {
    List<historySummary> batchList = list.subList(i, Math.min(i + batchSize, list.size()));
    mapper.insertBatchSomeColumn(batchList);
}

3. 使用事務(wù)管理

確保批量操作在事務(wù)中執(zhí)行,避免部分插入成功導(dǎo)致數(shù)據(jù)不一致。

@Transactional(rollbackFor = Exception.class)
public boolean batchInsert(List<historySummary> list) {
    int result = mapper.insertBatchSomeColumn(list);
    return result > 0;
}

4. 索引優(yōu)化

對插入頻繁的表,合理設(shè)計索引,避免過多不必要的索引影響插入性能。盡量減少在批量插入時的索引數(shù)量,插入完成后再創(chuàng)建必要的索引。

5. 禁用自動提交

在批量插入過程中,禁用自動提交,減少事務(wù)提交的次數(shù),提高性能。

jdbcTemplate.execute((ConnectionCallback<Void>) connection -> {
    connection.setAutoCommit(false);
    // 執(zhí)行批量插入操作
    connection.commit();
    return null;
});

參考

MybatisPlus自定義insertBatchSomeColumn實現(xiàn)真正批量插入 - CSDN博客

MybatisPlus如何實現(xiàn)insertBatchSomeColumn進(jìn)行批量增加 - 億速云

MyBatis-Plus 官方文檔

MySQL Connector/J Documentation

到此這篇關(guān)于MybatisPlus實現(xiàn)真正批量插入的文章就介紹到這了,更多相關(guān)MybatisPlus批量插入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring事件監(jiān)聽器之@EventListener原理分析

    Spring事件監(jiān)聽器之@EventListener原理分析

    這篇文章主要介紹了Spring事件監(jiān)聽器之@EventListener原理分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 如何解決java.util.concurrent.CancellationException問題

    如何解決java.util.concurrent.CancellationException問題

    這篇文章主要介紹了如何解決java.util.concurrent.CancellationException問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Spring Cloud 中@FeignClient注解中的contextId屬性詳解

    Spring Cloud 中@FeignClient注解中的contextId屬性詳解

    這篇文章主要介紹了Spring Cloud 中@FeignClient注解中的contextId屬性詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Spring實戰(zhàn)之獲得Bean本身的id操作示例

    Spring實戰(zhàn)之獲得Bean本身的id操作示例

    這篇文章主要介紹了Spring實戰(zhàn)之獲得Bean本身的id操作,結(jié)合實例形式分析了spring獲取Bean本身id的相關(guān)配置與實現(xiàn)技巧,需要的朋友可以參考下
    2019-11-11
  • Java異常處理 如何跟蹤異常的傳播路徑

    Java異常處理 如何跟蹤異常的傳播路徑

    這篇文章主要介紹了Java異常處理 如何跟蹤異常的傳播路徑,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • MybatisPlus實現(xiàn)分頁效果并解決錯誤問題:cant?found?IPage?for?args

    MybatisPlus實現(xiàn)分頁效果并解決錯誤問題:cant?found?IPage?for?args

    這篇文章主要介紹了MybatisPlus實現(xiàn)分頁效果并解決錯誤:cant?found?IPage?for?args,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-02-02
  • SpringBoot Jpa 自定義查詢實現(xiàn)代碼詳解

    SpringBoot Jpa 自定義查詢實現(xiàn)代碼詳解

    這篇文章主要介紹了SpringBoot Jpa 自定義查詢實現(xiàn)代碼詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • Java?NIO?Channel?使用詳情

    Java?NIO?Channel?使用詳情

    這篇文章主要介紹了Java?NIO?Channel?使用詳情,文章圍繞主題展開詳細(xì)內(nèi)容需要的小伙伴可以參考一下,希望對你的學(xué)習(xí)有所幫助
    2022-04-04
  • Java設(shè)計模式之靜態(tài)代理模式實例分析

    Java設(shè)計模式之靜態(tài)代理模式實例分析

    這篇文章主要介紹了Java設(shè)計模式之靜態(tài)代理模式,結(jié)合實例形式分析了靜態(tài)代理模式的概念、原理、定義與用法,需要的朋友可以參考下
    2018-04-04
  • 利用Maven入手Spring Boot第一個程序詳解

    利用Maven入手Spring Boot第一個程序詳解

    這篇文章主要給大家介紹了關(guān)于如何利用Maven入手Spring Boot第一個程序的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-02-02

最新評論

大兴区| 汪清县| 澄城县| 平湖市| 隆昌县| 武义县| 五大连池市| 涿鹿县| 福州市| 高密市| 合川市| 焉耆| 穆棱市| 东乡县| 榕江县| 高台县| 宜兰县| 沭阳县| 清苑县| 和林格尔县| 南召县| 双辽市| 林甸县| 布尔津县| 和龙市| 怀仁县| 贵德县| 兴仁县| 周口市| 灵石县| 巫山县| 阿拉善右旗| 宜春市| 黑龙江省| 甘孜| 苍梧县| 临夏市| 义马市| 梓潼县| 邢台县| 通州区|