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

如何使用MybatisPlus的SQL注入器提升批量插入性能

 更新時(shí)間:2024年05月21日 10:26:01   作者:戰(zhàn)斧  
本文給大家介紹如何使用MybatisPlus的SQL注入器提升批量插入性能,以實(shí)戰(zhàn)視角講述如何利用該特性提升MybatisPlus?的批量插入性能,感興趣的朋友跟隨小編一起看看吧

上一次我們給大家詳細(xì)講解 MybatisPlus 的條件構(gòu)造器wrapper。這次我們來講另一個(gè)開發(fā)者需要了解的功能——SQL注入器,并以實(shí)戰(zhàn)視角講述如何利用該特性提升MybatisPlus 的批量插入性能

一、SQL注入器是什么?

在上次的文章《MybatisPlus 構(gòu)造器wrapper的使用與原理》 的第三部分,我們講解了 MybatisPlus 運(yùn)行的一些原理

  • 獲取語法模板SQL

  • 代入表及字段信息

  • 代入條件構(gòu)造器邏輯

如果不太熟悉的,可以再去復(fù)習(xí)一遍。不難發(fā)現(xiàn)這第一步,就是獲取語法模板SQL,MybatisPlus源碼中就有不少簡單的模板,如下圖。但是坦白來說,對于一些大型的項(xiàng)目來說,內(nèi)置的SQL可能還是少了點(diǎn)

如果只是個(gè)別SQL有特殊的語法,那倒罷了,針對個(gè)別SQL寫個(gè)xml文件就可以解決。然而如果有很多SQL都使用同一個(gè)模板,那我們一個(gè)個(gè)去改就比較費(fèi)事了,而SQL注入器就能為我們解決這個(gè)困擾

二、批量插入的性能問題

1. saveBatch 的運(yùn)行原理

我們在日常使用中,可能會(huì)使用到IservicesaveBatch 方法來實(shí)現(xiàn)批量插入

但是如果我們繼續(xù)在源碼中深入,就可以發(fā)現(xiàn)這個(gè)批量插入本質(zhì)上是在for循環(huán)中插入,默認(rèn)以1000為一批,進(jìn)行一次刷新flush

雖然這里使用的同一個(gè)sqlSession能夠提高一些效率,但畢竟是for循環(huán)內(nèi)的插入,真在大批量插入時(shí)性能還是有待提升。而一個(gè)大項(xiàng)目中,批量插入的功能還是很常見的,本期我們就看看,如何使用 MybatisPlus的SQL注入器提升批量插入性能

2. 理想的批量插入形式

我們都知道,數(shù)據(jù)庫其實(shí)提供了批量插入的SQL樣式,比如Mysql的

INSERT INTO your_table_name (column1, column2, column3)
VALUES
(value1a, value2a, value3a),
(value1b, value2b, value3b),
(value1c, value2c, value3c);

而對于Oracle,其也有對應(yīng)的樣式

INSERT ALL
  INTO table_name (column1, column2, ...) VALUES (value1a, value2a, ...)
  INTO table_name (column1, column2, ...) VALUES (value1b, value2b, ...)
  INTO table_name (column1, column2, ...) VALUES (value1c, value2c, ...)
SELECT * FROM dual;

或者

INSERT INTO table_name (column1, column2, ...)
SELECT value1a, value2a, ...
  FROM dual
UNION ALL
SELECT value1b, value2b, ...
  FROM dual
UNION ALL
SELECT value1c, value2c, ...
  FROM dual;

使用對應(yīng)數(shù)據(jù)庫的批量插入樣式,毫無疑問是最合適的,所以我們需要在MybatisPlus中加入這樣的模板

三、構(gòu)造批量插入的SQL注入器

1. 自定義方法

首先我們要自定義一個(gè)方法,因?yàn)镸ysql 和 Oracle 的批量插入樣式不一樣,所以理論上要寫兩個(gè)方法,但實(shí)際上MybatisPlus 針對 Mysql 已經(jīng)有了一個(gè)內(nèi)置方法 InsertBatchSomeColumn,所以我們只需要針對 Oracle 自定義方法即可 繼承自·AbstractMethod

public class InsertBatchSomeColumnOracle extends AbstractMethod {
    // oracle 批量插入的格式
    private static String ORACLE_INSERT_SQL_MODE = "<script>\nINSERT ALL\n %s \n SELECT 1 FROM DUAL</script>";
    // 字段篩選條件
    @Setter
    @Accessors(chain = true)
    private Predicate<TableFieldInfo> predicate;
    public InsertBatchSomeColumnOracle() {
        super("insertBatchSomeColumnOracle");
    }
    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        KeyGenerator keyGenerator = new NoKeyGenerator();
        List<TableFieldInfo> fieldList = tableInfo.getFieldList();
        String insertSqlColumn = tableInfo.getKeyInsertSqlColumn(true, false)
                + this.filterTableFieldInfo(fieldList, predicate, TableFieldInfo::getInsertSqlColumn, EMPTY);
        String columnScript = LEFT_BRACKET + insertSqlColumn.substring(0, insertSqlColumn.length() - 1) + RIGHT_BRACKET;
        String insertSqlProperty = tableInfo.getKeyInsertSqlProperty(true, ENTITY_DOT, false) + this.filterTableFieldInfo(fieldList, predicate, i -> i.getInsertSqlProperty(ENTITY_DOT), EMPTY);
        insertSqlProperty = LEFT_BRACKET + insertSqlProperty.substring(0, insertSqlProperty.length() - 1) + RIGHT_BRACKET;
        String oracleModelInsertSql = "INTO " + tableInfo.getTableName() + columnScript + " VALUES " + insertSqlProperty;
        String valuesScript = SqlScriptUtils.convertForeach(oracleModelInsertSql, "list", null, ENTITY, " ");
        String keyProperty = null;
        String keyColumn = null;
        //表包含主鍵處理邏輯,如果不包含主鍵當(dāng)普通字段處理
        if (tableInfo.havePK()) {
            if (tableInfo.getIdType() == IdType.AUTO) {
                /* 自增主鍵 */
                keyGenerator = new Jdbc3KeyGenerator();
                keyProperty = tableInfo.getKeyProperty();
                keyColumn = tableInfo.getKeyColumn();
            } else {
                if (null != tableInfo.getKeySequence()) {
                    Keybenerator:
                    TableInfoHelper.genKeyGenerator("insertBatchSomeColumnOracle", tableInfo, builderAssistant);
                    keyProperty = tableInfo.getKeyProperty();
                    keyColumn = tableInfo.getKeyColumn();
                }
            }
        }
        String sql = String.format(ORACLE_INSERT_SQL_MODE, valuesScript);
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        return this.addInsertMappedStatement(mapperClass, modelClass, "insertBatchSomeColumnOracle", sqlSource, keyGenerator, keyProperty, keyColumn);
    }
}

2. 將方法注入 MybatisPlus

僅僅寫一個(gè)類,并不能直接就使用,我們還需要把這個(gè)方法,融入 MybatisPlus 的運(yùn)行時(shí)。這時(shí)就要用到另一個(gè)類,這個(gè)類要繼承
DefaultSqlInjector,如下,我們把mysql 和 oracle 的兩個(gè)批量插入都加入 methodList 中

public class CustomerSqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperclass, TableInfo tableInfo) {
        List<AbstractMethod> methodList = super.getMethodList(mapperclass, tableInfo);
        // 真正的批量插入,添加 InsertBatchSomeColumn 方法,以下僅適用于 MySQL
        methodList.add(new InsertBatchSomeColumn());
        // 真正的批量插入,添加 InsertBatchSomeColumn 方法,以下僅適用于 oracle
        methodList.add(new InsertBatchSomeColumnOracle());
        return methodList;
    }
}

3. 創(chuàng)建使用方法的接口

上面的內(nèi)容是把新增的方法放入MybatisPlus,下面我們還需要一個(gè)給開發(fā)者使用的入口

public interface CustomerMapper<T> extends BaseMapper<T> {
    void insertBatchSomeColumn(@Param("list") List<T> list);
    void insertBatchSomeColumnOracle(@Param("list") List<T> list);
}

當(dāng)然,構(gòu)建完Mapper級別,你也可以繼續(xù)往上構(gòu)建,比如構(gòu)建自己的Service級(接口及實(shí)現(xiàn)類),如下

public interface CustomerService<T> extends Iservice<T> {
    void insertBatchSomeColumn(List<T> list);
    void insertBatchSomeColumnOracle(List<T> list);
}

4. 啟用該注入器

現(xiàn)在代碼層面的配置解決了,想要使用批量插入功能的,只要讓我們的Mapper接口繼承CostomerMapper就可以,如下:

@Mapper
public interface CsdnUserInfoMapper extends CustomerMapper<CsdnUserInfo> {
}

然后我們還需要在配置中開啟這個(gè)注入器。我們可以在yml文件中這么配置

mybatis-plus:
  global-config:
    sql-injector: com.example.MyLogicSqlInjector

四、總結(jié)

在上面的學(xué)習(xí)里,我們詳細(xì)闡述了如何使用 MybatisPlus的SQL注入器提升批量插入性能,希望幫大家更深入的了解 MybatisPlus 的特性及其使用,也希望能幫助大家開闊性能優(yōu)化的思路,后續(xù)我們將繼續(xù)為大家講解 MybatisPlus 的更多內(nèi)容

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

相關(guān)文章

  • Java常用 Date 時(shí)間格式化、Calender日歷、正則表達(dá)式的用法小結(jié)

    Java常用 Date 時(shí)間格式化、Calender日歷、正則表達(dá)式的用法小結(jié)

    SimpleDateFormat?是Java中用于格式化和解析日期的類,它允許你將日期對象轉(zhuǎn)換為特定格式的字符串,或者將特定格式的字符串轉(zhuǎn)換為日期對象,這篇文章主要介紹了Java常用 Date 時(shí)間格式化、Calender日歷、正則表達(dá)式的用法,需要的朋友可以參考下
    2024-12-12
  • 淺談hibernate急迫加載問題(多重外鍵關(guān)聯(lián))

    淺談hibernate急迫加載問題(多重外鍵關(guān)聯(lián))

    這篇文章主要介紹了淺談hibernate急迫加載問題(多重外鍵關(guān)聯(lián)),具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Java創(chuàng)建樹形結(jié)構(gòu)算法實(shí)例代碼

    Java創(chuàng)建樹形結(jié)構(gòu)算法實(shí)例代碼

    本篇文章主要介紹了Java創(chuàng)建樹形結(jié)構(gòu)算法實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-01-01
  • Java實(shí)現(xiàn)查找Excel數(shù)據(jù)并高亮顯示

    Java實(shí)現(xiàn)查找Excel數(shù)據(jù)并高亮顯示

    在日常的開發(fā)工作中,我們經(jīng)常需要處理各種格式的數(shù)據(jù),本文將為您詳細(xì)介紹如何利用強(qiáng)大的第三方庫 Spire.XLS for Java,輕松實(shí)現(xiàn) Excel 數(shù)據(jù)的查找與高亮功能,有需要的小伙伴可以了解下
    2025-09-09
  • Jenkins 編譯后使用SSH發(fā)布詳解

    Jenkins 編譯后使用SSH發(fā)布詳解

    這篇文章主要介紹了Jenkins 編譯后使用SSH發(fā)布詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • 一文徹底弄懂spring?boot自動(dòng)配置的過程(推薦)

    一文徹底弄懂spring?boot自動(dòng)配置的過程(推薦)

    SpringBoot的自動(dòng)配置機(jī)制通過@SpringBootApplication注解作為起點(diǎn),結(jié)合@EnableAutoConfiguration和spring.factories文件,實(shí)現(xiàn)了基于類路徑依賴、環(huán)境配置和自定義代碼的智能化配置,感興趣的朋友跟隨小編一起看看吧
    2024-10-10
  • Java http請求封裝工具類代碼實(shí)例

    Java http請求封裝工具類代碼實(shí)例

    這篇文章主要介紹了Java http請求封裝工具類代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • SpringMVC的ModelAndView傳值方法

    SpringMVC的ModelAndView傳值方法

    今天小編就為大家分享一篇SpringMVC的ModelAndView傳值方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • mybatis-plus批量更新updateBatchById問題

    mybatis-plus批量更新updateBatchById問題

    這篇文章主要介紹了mybatis-plus批量更新updateBatchById問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Java?在游戲中探索數(shù)組二維數(shù)組

    Java?在游戲中探索數(shù)組二維數(shù)組

    數(shù)組和二維數(shù)組感覺用王者榮耀的裝備欄來舉例解釋,應(yīng)該更易懂一些。從基礎(chǔ)開始講,后續(xù)會(huì)講到JAVA高級,中間會(huì)穿插面試題和項(xiàng)目實(shí)戰(zhàn),希望能給大家?guī)韼椭?/div> 2022-03-03

最新評論

北流市| 绥中县| 从江县| 临猗县| 大关县| 汉川市| 图们市| 庄浪县| 马鞍山市| 迁安市| 大连市| 连平县| 离岛区| 乡宁县| 乌拉特中旗| 海南省| 北辰区| 伊宁市| 石渠县| 武功县| 清徐县| 西乌珠穆沁旗| 高雄市| 陆良县| 金溪县| 襄垣县| 托里县| 安康市| 滨海县| 英吉沙县| 旬邑县| 万盛区| 西城区| 丰都县| 灵寿县| 内黄县| 岳池县| 莎车县| 吴川市| 云安县| 靖安县|