Mybatis-Plus save和saveBatch方法忽略自增主鍵詳解
Mybatis-Plus save和saveBatch方法忽略自增主鍵
這個mybatisplus版本從3.4.0升級到3.5.6之后原來涉及到save和saveBatch方法的地方會報主鍵沖突
org.springframework.dao.DuplicateKeyException:
### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '*' for key '*****.PRIMARY'
各大搜索引擎搜索了一圈,都沒有關(guān)于這個問題的答案,于是只能跟蹤mybatisplus代碼進去一探究竟
在MybatisPlusAutoConfiguration創(chuàng)建SqlSessionFactory對象后會
從跟蹤情況得知sql語句的生成是在服務(wù)啟動的時候就加載生成了的。
在MybatisConfiguration類中創(chuàng)建SqlSessionFactory對象
創(chuàng)建過程中遍歷mapperLocations使用MybatisXMLMapperBuilder對Mapper文件進行解析,中間步驟跳過,因為我們跟蹤的是save和saveBatch這兩個方法最終調(diào)用的是Mapper.insert方法,所以只需看Insert類即可,上面解析方法為insert通過Insert類來完成
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);
}
}這個類代碼不多,只有一個方法injectMappedStatement,關(guān)鍵代碼就在這個方法的columnScript變量賦值上面getAllInsertSqlColumnMaybeIf((String)null, this.ignoreAutoIncrementColumn)
這個方法有個傳參ignoreAutoIncrementColumn,是Insert類的成員變量
這個值的默認值是false,在3.4.0的版本中是沒有的
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就少了這個屬性,而columnScript賦值的后面方法中如果主鍵策略是IdType.AUTO也就是自增主鍵的話默認是不帶主鍵返回的
所以如果3.4.0的版本用了save或saveBatch方法并且?guī)Я酥麈I值升級為3.5.6后需要手動設(shè)置
mybatis-plus.global-config.db-config.insertIgnoreAutoIncrementColumn=true
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- mybatis-plus如何根據(jù)任意字段saveOrUpdateBatch
- MyBatis-Plus:saveOrUpdate根據(jù)指定字段更新或插入方式
- mybatis-plus saveOrUpdateBatch踩坑記錄
- Mybatis-Plus的saveOrUpdateBatch(null)問題及解決
- 怎樣提高mybatis-plus中saveBatch方法的效率
- mybatis-plus 關(guān)于savebatch,saveorupdatebatch遇到的坑及解決辦法
- Mybatis-Plus saveBatch()批量保存失效的解決
- Mybatis-Plus使用saveOrUpdate及問題解決方法
相關(guān)文章
Java 回調(diào)機制(CallBack) 詳解及實例代碼
這篇文章主要介紹了 Java 回調(diào)機制(CallBack) 詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02
Java實現(xiàn)上傳和下載功能(支持多個文件同時上傳)
這篇文章主要介紹了Java實現(xiàn)上傳和下載功能,支持多個文件同時上傳,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-12-12
springmvc中進行數(shù)據(jù)保存以及日期參數(shù)的保存過程解析
這篇文章主要介紹了springmvc中進行數(shù)據(jù)保存以及日期參數(shù)的保存過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-09-09
解釋為什么Java中“1000==1000”為false而”100==100“為true
在日常編程中,我們經(jīng)常遇到一些看似簡單卻隱藏著復雜邏輯的問題,這篇文章主要介紹了解釋為什么Java中“1000==1000”為false而”100==100“為true,需要的朋友可以參考下2024-01-01

