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

Mybatis-Plus save和saveBatch方法忽略自增主鍵詳解

 更新時(shí)間:2025年12月15日 08:45:15   作者:duchx  
Mybatis-Plus在從3.4.0升級(jí)到3.5.6后,save和saveBatch方法在處理自增主鍵時(shí)會(huì)出現(xiàn)主鍵沖突的問(wèn)題,這是因?yàn)?.5.6版本中增加了`ignoreAutoIncrementColumn`屬性,默認(rèn)值為false,導(dǎo)致在生成SQL語(yǔ)句時(shí)忽略了自增主鍵,解決方法是手動(dòng)設(shè)置主鍵值

Mybatis-Plus save和saveBatch方法忽略自增主鍵

這個(gè)mybatisplus版本從3.4.0升級(jí)到3.5.6之后原來(lái)涉及到save和saveBatch方法的地方會(huì)報(bào)主鍵沖突

org.springframework.dao.DuplicateKeyException:
### Error updating database.  Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '*' for key '*****.PRIMARY'

各大搜索引擎搜索了一圈,都沒(méi)有關(guān)于這個(gè)問(wèn)題的答案,于是只能跟蹤mybatisplus代碼進(jìn)去一探究竟

在MybatisPlusAutoConfiguration創(chuàng)建SqlSessionFactory對(duì)象后會(huì)

從跟蹤情況得知sql語(yǔ)句的生成是在服務(wù)啟動(dòng)的時(shí)候就加載生成了的。

在MybatisConfiguration類中創(chuàng)建SqlSessionFactory對(duì)象

創(chuàng)建過(guò)程中遍歷mapperLocations使用MybatisXMLMapperBuilder對(duì)Mapper文件進(jìn)行解析,中間步驟跳過(guò),因?yàn)槲覀兏櫟氖莝ave和saveBatch這兩個(gè)方法最終調(diào)用的是Mapper.insert方法,所以只需看Insert類即可,上面解析方法為insert通過(guò)Insert類來(lái)完成

public class Insert extends AbstractMethod {
    private boolean ignoreAutoIncrementColumn;

    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        KeyGenerator keyGenerator = NoKeyGenerator.INSTANCE;
        SqlMethod sqlMethod = SqlMethod.INSERT_ONE;
        String columnScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlColumnMaybeIf((String)null, this.ignoreAutoIncrementColumn), "(", ")", (String)null, ",");
        String valuesScript = "(\n" + SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlPropertyMaybeIf((String)null, this.ignoreAutoIncrementColumn), (String)null, (String)null, (String)null, ",") + "\n" + ")";
        String keyProperty = null;
        String keyColumn = null;
        if (StringUtils.isNotBlank(tableInfo.getKeyProperty())) {
            if (tableInfo.getIdType() == IdType.AUTO) {
                keyGenerator = Jdbc3KeyGenerator.INSTANCE;
                keyProperty = tableInfo.getKeyProperty();
                keyColumn = SqlInjectionUtils.removeEscapeCharacter(tableInfo.getKeyColumn());
            } else if (null != tableInfo.getKeySequence()) {
                keyGenerator = TableInfoHelper.genKeyGenerator(this.methodName, tableInfo, this.builderAssistant);
                keyProperty = tableInfo.getKeyProperty();
                keyColumn = tableInfo.getKeyColumn();
            }
        }

        String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), columnScript, valuesScript);
        SqlSource sqlSource = super.createSqlSource(this.configuration, sql, modelClass);
        return this.addInsertMappedStatement(mapperClass, modelClass, this.methodName, sqlSource, (KeyGenerator)keyGenerator, keyProperty, keyColumn);
    }
}

這個(gè)類代碼不多,只有一個(gè)方法injectMappedStatement,關(guān)鍵代碼就在這個(gè)方法的columnScript變量賦值上面getAllInsertSqlColumnMaybeIf((String)null, this.ignoreAutoIncrementColumn)
這個(gè)方法有個(gè)傳參ignoreAutoIncrementColumn,是Insert類的成員變量

這個(gè)值的默認(rèn)值是false,在3.4.0的版本中是沒(méi)有的

3.4.0的版本代碼

public class Insert extends AbstractMethod {
    public Insert() {
    }

    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        KeyGenerator keyGenerator = new NoKeyGenerator();
        SqlMethod sqlMethod = SqlMethod.INSERT_ONE;
        String columnScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlColumnMaybeIf((String)null), "(", ")", (String)null, ",");
        String valuesScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlPropertyMaybeIf((String)null), "(", ")", (String)null, ",");
        String keyProperty = null;
        String keyColumn = null;
        if (StringUtils.isNotBlank(tableInfo.getKeyProperty())) {
            if (tableInfo.getIdType() == IdType.AUTO) {
                keyGenerator = new Jdbc3KeyGenerator();
                keyProperty = tableInfo.getKeyProperty();
                keyColumn = tableInfo.getKeyColumn();
            } else if (null != tableInfo.getKeySequence()) {
                keyGenerator = TableInfoHelper.genKeyGenerator(this.getMethod(sqlMethod), tableInfo, this.builderAssistant);
                keyProperty = tableInfo.getKeyProperty();
                keyColumn = tableInfo.getKeyColumn();
            }
        }

        String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), columnScript, valuesScript);
        SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
        return this.addInsertMappedStatement(mapperClass, modelClass, this.getMethod(sqlMethod), sqlSource, (KeyGenerator)keyGenerator, keyProperty, keyColumn);
    }
}

比3.5.6就少了這個(gè)屬性,而columnScript賦值的后面方法中如果主鍵策略是IdType.AUTO也就是自增主鍵的話默認(rèn)是不帶主鍵返回的

所以如果3.4.0的版本用了save或saveBatch方法并且?guī)Я酥麈I值升級(jí)為3.5.6后需要手動(dòng)設(shè)置

mybatis-plus.global-config.db-config.insertIgnoreAutoIncrementColumn=true

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

将乐县| 滨海县| 金山区| 高雄市| 隆林| 洪湖市| 喀喇沁旗| 赞皇县| 偏关县| 南木林县| 永城市| 嵩明县| 临沭县| 永昌县| 安化县| 青岛市| 芦山县| 阿合奇县| 旌德县| 阆中市| 体育| 吉林市| 涟源市| 越西县| 江孜县| 青浦区| 剑河县| 仁布县| 通化市| 江孜县| 枣庄市| 睢宁县| 南丹县| 金华市| 高邑县| 来凤县| 鸡西市| 偃师市| 肇源县| 乐平市| 前郭尔|