mybatis-plus 擴(kuò)展批量新增的實(shí)現(xiàn)
前言
最近發(fā)現(xiàn)公司的微服務(wù)項(xiàng)目中沒有統(tǒng)一的批量新增方法,公司用的是MP插件,遇到批量新增都是單獨(dú)去去編寫xml實(shí)現(xiàn),費(fèi)時(shí)費(fèi)力,而MP自帶的批插方法只是實(shí)現(xiàn)了分批條sql,跟真正意義上一條sql實(shí)現(xiàn)批插還是有很大的性能差異,所以決定實(shí)現(xiàn)一個(gè)統(tǒng)一的批插方法。
一、MP如何擴(kuò)展批量新增方法?
MP給我們預(yù)留了一個(gè)可以真正實(shí)現(xiàn)批插的插件InsertBatchSomeColumn,但是只是針對(duì)mysql數(shù)據(jù)庫的,我們可以參照它稍加改造擴(kuò)展一個(gè)針對(duì)oracle或者其他數(shù)據(jù)庫的批插插件類,然后通過sql注入器的方式注入并初始化,就可以實(shí)現(xiàn)真正的批插了。
二、實(shí)現(xiàn)步驟
1.擴(kuò)展批插類
代碼如下(示例):
public class InsertBatchSomeColumnOracle extends AbstractMethod { ? ? /** ? ? ?* 字段篩選條件 ? ? ?*/ ? ? @Setter ? ? @Accessors(chain = true) ? ? private Predicate<TableFieldInfo> predicate; ? ? @SuppressWarnings("Duplicates") ? ? @Override ? ? public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) { ? ? ? ? KeyGenerator keyGenerator = new NoKeyGenerator(); ? ? ? ? SqlMethod sqlMethod = SqlMethod.INSERT_ALL; ? ? ? ? List<TableFieldInfo> fieldList = tableInfo.getFieldList(); ? ? ? ? String insertSqlColumn = tableInfo.getKeyInsertSqlColumn(false) + ? ? ? ? ? ? ? ? this.filterTableFieldInfo(fieldList, predicate, TableFieldInfo::getInsertSqlColumn, EMPTY); ? ? ? ? String tableName = tableInfo.getTableName(); ? ? ? ? String columnScript = LEFT_BRACKET + insertSqlColumn.substring(0, insertSqlColumn.length() - 1) + RIGHT_BRACKET; ? ? ? ? String insertSqlProperty = tableInfo.getKeyInsertSqlProperty(ENTITY_DOT, false) + ? ? ? ? ? ? ? ? this.filterTableFieldInfo(fieldList, predicate, i -> i.getInsertSqlProperty(ENTITY_DOT), EMPTY); ? ? ? ? insertSqlProperty = " into " + tableName + columnScript + " values " + LEFT_BRACKET + insertSqlProperty.substring(0, insertSqlProperty.length() - 1) + RIGHT_BRACKET; ? ? ? ? String batchScript = SqlScriptUtils.convertForeach(insertSqlProperty, "list", null, ENTITY, EMPTY); ? ? ? ? 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()) { ? ? ? ? ? ? ? ? ? ? keyGenerator = TableInfoHelper.genKeyGenerator(getMethod(), tableInfo, builderAssistant); ? ? ? ? ? ? ? ? ? ? keyProperty = tableInfo.getKeyProperty(); ? ? ? ? ? ? ? ? ? ? keyColumn = tableInfo.getKeyColumn(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? String sql = String.format(sqlMethod.getSql(), batchScript); ? ? ? ? SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); ? ? ? ? return this.addInsertMappedStatement(mapperClass, modelClass, getMethod(), sqlSource, keyGenerator, keyProperty, keyColumn); ? ? } ? ? public String getMethod() { ? ? ? ? // 自定義 mapper 方法名 ? ? ? ? return "insertBatchSomeColumnOracle"; ? ? } }
2.編寫sql注入器
代碼如下(示例):
public class MpSqlInjector extends DefaultSqlInjector { ? ? @Override ? ? public List<AbstractMethod> getMethodList(Class<?> mapperClass) { ? ? ? ? // 防止父類的方法不可使用 ? ? ? ? List<AbstractMethod> methodList = super.getMethodList(mapperClass); ? ? ? ? // 添加批量插入的方法 ? ? ? ? methodList.add(new InsertBatchSomeColumn()); ? ? ? ? methodList.add(new InsertBatchSomeColumnOracle()); ? ? ? ? return methodList; ? ? } }
3.spring容器中實(shí)例化sql注入器
代碼如下(示例):
@Bean public MpSqlInjector mpSqlInjector() { ? ? return new MpSqlInjector(); }
4.業(yè)務(wù)代碼實(shí)現(xiàn)
代碼如下(示例):
public interface MyBaseMapper<T> extends BaseMapper<T> { ? ? /** ? ? ?* 批量插入 (mysql) ? ? ?* @param entityList 實(shí)體列表 ? ? ?* @return 影響行數(shù) ? ? ?*/ ? ? int insertBatchSomeColumn(Collection<T> entityList); ? ? /** ? ? ?* 批量插入 (oracle) ? ? ?* @param entityList 實(shí)體列表 ? ? ?* @return 影響行數(shù) ? ? ?*/ ? ? int insertBatchSomeColumnOracle(Collection<T> entityList); } /** ? ? ?* 批量插入記錄(選擇字段,策略插入) ? ? ?* ? ? ?* @param entityList 實(shí)體對(duì)象集合 ? ? ?*/ ? ? public void saveBatch(Collection<T> entityList) { ? ? ? ? if (DEFAULT_MUST_SAVE_BATCH) { ? ? ? ? ? ? ServiceAssert.isTrue(CollectionUtil.isNotEmpty(entityList), "批量插入傳入空集合, 插入失敗"); ? ? ? ? } ? ? ? ? if (CollectionUtil.isEmpty(entityList)) { ? ? ? ? ? ? return; ? ? ? ? } ? ? ? ? int res; ? ? ? ? if (DATABASE_TYPE_ORACLE.equalsIgnoreCase(dbType)) { ? ? ? ? ? ? res = getBaseMapper().insertBatchSomeColumnOracle(entityList); ? ? ? ? } else { ? ? ? ? ? ? res = getBaseMapper().insertBatchSomeColumn(entityList); ? ? ? ? } ? ? ? ? ServiceAssert.isTrue(res == entityList.size(), "插入失敗,請(qǐng)聯(lián)系管理員"); ? ? }
? ? /** ? ? ?* 批量插入記錄(選擇字段,策略插入) ? ? ?* ? ? ?* @param entityList 實(shí)體對(duì)象集合 ? ? ?* @param batchSize 每批次插入數(shù) ? ? ?*/ ? ? public void saveBatch(Collection<T> entityList, int batchSize) { ? ? ? ? if (DEFAULT_MUST_SAVE_BATCH) { ? ? ? ? ? ? ServiceAssert.isTrue(CollectionUtil.isNotEmpty(entityList), "批量插入傳入空集合, 插入失敗"); ? ? ? ? } ? ? ? ? if (CollectionUtil.isEmpty(entityList)) { ? ? ? ? ? ? return; ? ? ? ? } ? ? ? ? int size = entityList.size(); ? ? ? ? int idxLimit = Math.min(batchSize, size); ? ? ? ? int i = 1; ? ? ? ? //保存單批提交的數(shù)據(jù)集合 ? ? ? ? List<T> batchList = new ArrayList<>(); ? ? ? ? for(Iterator<T> it = entityList.iterator(); it.hasNext(); ++i) { ? ? ? ? ? ? T element = it.next(); ? ? ? ? ? ? batchList.add(element); ? ? ? ? ? ? int res; ? ? ? ? ? ? if (i == idxLimit) { ? ? ? ? ? ? ? ? if (DATABASE_TYPE_ORACLE.equalsIgnoreCase(dbType)) { ? ? ? ? ? ? ? ? ? ? res = getBaseMapper().insertBatchSomeColumnOracle(batchList); ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? res = getBaseMapper().insertBatchSomeColumn(batchList); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? //每次提交后需要清空集合數(shù)據(jù) ? ? ? ? ? ? ? ? batchList.clear(); ? ? ? ? ? ? ? ? idxLimit = Math.min(idxLimit + batchSize, size); ? ? ? ? ? ? ? ? ServiceAssert.isTrue(res == entityList.size(), "插入失敗,請(qǐng)聯(lián)系管理員"); ? ? ? ? ? ? } ? ? ? ? } ? ? }
總結(jié)
遇到問題可以看看源碼,說不定作者已經(jīng)給你留好路了。
到此這篇關(guān)于mybatis-plus 擴(kuò)展批量新增的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)mybatis-plus 批量新增內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Failed to execute goal org...的解決辦法
這篇文章主要介紹了Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1的解決辦法的相關(guān)資料,需要的朋友可以參考下2017-06-06java 獲取日期的幾天前,幾個(gè)月前和幾年前的實(shí)例
下面小編就為大家?guī)硪黄猨ava 獲取日期的幾天前,幾個(gè)月前和幾年前的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10java使用歸并刪除法刪除二叉樹中節(jié)點(diǎn)的方法
這篇文章主要介紹了java使用歸并刪除法刪除二叉樹中節(jié)點(diǎn)的方法,實(shí)例分析了java二叉樹算法的相關(guān)操作技巧,需要的朋友可以參考下2015-05-05APP轉(zhuǎn)盤抽獎(jiǎng)Java服務(wù)端接口詳解
這篇文章主要為大家詳細(xì)介紹了APP轉(zhuǎn)盤抽獎(jiǎng)Java服務(wù)端接口,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01Java項(xiàng)目開發(fā)中實(shí)現(xiàn)分頁的三種方式總結(jié)
這篇文章主要給大家介紹了關(guān)于Java項(xiàng)目開發(fā)中實(shí)現(xiàn)分頁的三種方式,通過這一篇文章可以很快的學(xué)會(huì)java分頁功能,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-02-02不到十行實(shí)現(xiàn)javaCV圖片OCR文字識(shí)別
識(shí)別圖片中的文字,會(huì)省很多時(shí)間,本文介紹了javaCV圖片OCR文字識(shí)別,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05Java 使用poi把數(shù)據(jù)庫中數(shù)據(jù)導(dǎo)入Excel的解決方法
本篇文章介紹了,Java 使用poi把數(shù)據(jù)庫中數(shù)據(jù)導(dǎo)入Excel的解決方法。需要的朋友參考下2013-05-05Java服務(wù)如何調(diào)用系統(tǒng)指令、Bat腳本記錄
這篇文章主要介紹了Java服務(wù)如何調(diào)用系統(tǒng)指令、Bat腳本記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06