亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

如何使用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多線程實(shí)現(xiàn)文件下載

    java多線程實(shí)現(xiàn)文件下載

    這篇文章主要為大家詳細(xì)介紹了java多線程實(shí)現(xiàn)文件下載,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • SpringMVC接收java.util.Date類型數(shù)據(jù)的2種方式小結(jié)

    SpringMVC接收java.util.Date類型數(shù)據(jù)的2種方式小結(jié)

    這篇文章主要介紹了使用SpringMVC接收java.util.Date類型數(shù)據(jù)的2種方法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • springboot jasypt2.x與jasypt3.x的使用方式

    springboot jasypt2.x與jasypt3.x的使用方式

    在軟件開發(fā)中,將配置文件中的敏感信息(如數(shù)據(jù)庫密碼)進(jìn)行加密是保障安全的有效手段,jasypt框架提供了這一功能,支持通過加密工具類或命令行工具生成密文,并通過修改配置文件和啟動(dòng)參數(shù)的方式使用密文和密鑰,這樣即便配置文件被泄露
    2024-09-09
  • SWT(JFace)體驗(yàn)之FormLayout布局

    SWT(JFace)體驗(yàn)之FormLayout布局

    SWT(JFace)體驗(yàn)之FormLayout布局示例代碼。
    2009-06-06
  • 如何在Spring Boot中建立連接及測試

    如何在Spring Boot中建立連接及測試

    對于剛接觸MQTT的開發(fā)者來說,了解如何在Spring Boot項(xiàng)目中集成MQTT客戶端并建立連接是邁向?qū)嶋H應(yīng)用的重要一步,今天,我將分享一個(gè)詳細(xì)的入門指南,帶你一步步在Spring Boot中建立MQTT連接,并通過JUnit進(jìn)行簡單的單元測試,感興趣的朋友一起看看吧
    2024-12-12
  • Java String不可變性實(shí)現(xiàn)原理解析

    Java String不可變性實(shí)現(xiàn)原理解析

    這篇文章主要介紹了Java String不可變性實(shí)現(xiàn)原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Spring AOP的概念與實(shí)現(xiàn)過程詳解

    Spring AOP的概念與實(shí)現(xiàn)過程詳解

    AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,可通過運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP是 Spring框架中的一個(gè)重要內(nèi)容
    2023-02-02
  • Java掩碼的幾種使用例舉

    Java掩碼的幾種使用例舉

    今天小編就為大家分享一篇關(guān)于Java掩碼的使用,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 淺談Java8新特性Predicate接口

    淺談Java8新特性Predicate接口

    這篇文章主要介紹了淺談Java8新特性Predicate接口,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-05-05
  • java身份證驗(yàn)證代碼實(shí)現(xiàn)

    java身份證驗(yàn)證代碼實(shí)現(xiàn)

    java身份證驗(yàn)證代碼實(shí)現(xiàn),需要的朋友可以參考一下
    2013-02-02

最新評論