mybatis-sqlserver批量新增返回id方式
遇到的問題
公司最近接到項目需要使用SqlServer,在做SQL兼容的時候遇到問題,批量新增數(shù)據(jù)時只返回的第一條記錄的id
解決思路
1.參考mysql
<insert id="batchInsert" userGeneratedKeys="true" keyProperty="id"> insert into public_user (name,password) values <foreach collection="list" separator="," item="item"> (#{item.name}, #{itme.password}) </foreach> </insert>
具體mybatis封裝id的地方在org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator
主要邏輯是通過Statement.getGeneratedKeys()獲取id結(jié)果集.
SqlServer只能獲取第一個
2.發(fā)現(xiàn)上述步驟的Jdbc3KeyGenerator是有接口的KeyGenerator,查看后發(fā)現(xiàn)有3個實現(xiàn)類了解到SelectKeyGenerator通過selectKeyt標(biāo)簽可以返回id;
3.查看SelectKeyGenerator源碼了解到只支持返回單個id;
4.通過百度了解到SqlServer通過output inserted.id可以輸出id;
5.是否可以自己實現(xiàn)KeyGenerator來解決批量返回id的方法呢?
6.最后我沒找到配置自定義的實現(xiàn)類的方式,決定通過mybatis的攔截器解決
代碼
mybatis攔截器
@Component @Intercepts(@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})) public class SqlServerKeyGeneratorInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 正常執(zhí)行代碼 獲取返回結(jié)構(gòu)集 List<Object> values = (List)invocation.proceed(); MappedStatement ms = (MappedStatement) invocation.getArgs()[0]; // 判斷是否selectKey查詢語句 if (ms.getId().endsWith(SelectKeyGenerator.SELECT_KEY_SUFFIX)) { Configuration configuration = ms.getConfiguration(); // 處理入?yún)ο? Collection<Object> parameters = getParameters(invocation.getArgs()[1]); // 封裝id for (int i = 0; i < parameters.size(); i++) { MetaObject metaObject = configuration.newMetaObject(parameters.toArray()[i]); metaObject.setValue("id", Long.valueOf((Integer)(((Map)values.get(i)).get("id")))); } // 返回假數(shù)據(jù)防止異常 List<Long> ids = new ArrayList<>(); ids.add(1L); return ids; } return values; } @Override public Object plugin(Object target) { return null; } @Override public void setProperties(Properties properties) { } /** 來源 Jdbc3KeyGenerator */ private Collection<Object> getParameters(Object parameter) { Collection<Object> parameters = null; if (parameter instanceof Collection) { parameters = (Collection) parameter; } else if (parameter instanceof Map) { Map parameterMap = (Map) parameter; if (parameterMap.containsKey("collection")) { parameters = (Collection) parameterMap.get("collection"); } else if (parameterMap.containsKey("list")) { parameters = (List) parameterMap.get("list"); } else if (parameterMap.containsKey("array")) { parameters = Arrays.asList((Object[]) parameterMap.get("array")); } } if (parameters == null) { parameters = new ArrayList<Object>(); parameters.add(parameter); } return parameters; } }
mapper
<insert id="batchInsert"> <selectKey keyColumn="id" keyProperty="id" order="AFTER" resultType="java.util.Map"> insert into public_user (name,password) output inserted.id values <foreach collection="list" separator="," item="item"> (#{item.name}, #{itme.password}) </foreach> <selectKey> </insert>
PS:
需要注意的是id對象參數(shù)必須放在第一位,攔截器的代碼寫的比較粗糙,給各位提供思路。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
MyBatis-Plus通過插件將數(shù)據(jù)庫表生成Entiry,Mapper.xml,Mapper.class的方式
今天小編就為大家分享一篇關(guān)于MyBatis-Plus通過插件將數(shù)據(jù)庫表生成Entiry,Mapper.xml,Mapper.class的方式,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-02-02Spring Boot中使用RabbitMQ 生產(chǎn)消息和消費(fèi)消息的實例代碼
本文介紹了在SpringBoot中如何使用RabbitMQ進(jìn)行消息的生產(chǎn)和消費(fèi),詳細(xì)闡述了RabbitMQ中交換機(jī)的作用和類型,包括直連交換機(jī)、主題交換機(jī)、扇出交換機(jī)和頭交換機(jī),并解釋了各自的消息路由機(jī)制,感興趣的朋友一起看看吧2024-10-10SpringMVC開發(fā)restful API之用戶查詢代碼詳解
這篇文章主要介紹了SpringMVC開發(fā)restful API之用戶查詢代碼詳解,小編覺得挺不錯的,這里分享給大家,需要的朋友可以參考。下面隨小編一起看看吧。2017-11-11Spring Cloud 動態(tài)刷新配置信息教程詳解
這篇文章主要介紹了Spring Cloud 動態(tài)刷新配置信息的教程,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-06-06Java?spring?MVC環(huán)境中實現(xiàn)WebSocket的示例代碼
這篇文章主要介紹了Java?spring?MVC環(huán)境中實現(xiàn)WebSocket,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09jvm內(nèi)存溢出解決方法(jvm內(nèi)存溢出怎么解決)
jvm內(nèi)存溢出解決方法,詳細(xì)內(nèi)容看下面解釋2013-12-12SpringBoot集成ShedLock實現(xiàn)分布式定時任務(wù)的示例代碼
ShedLock 是一個 Java 庫,通常用于分布式系統(tǒng)中,確保定時任務(wù)(Scheduled Tasks)在集群環(huán)境下只被某一個實例執(zhí)行一次,本文給大家介紹了SpringBoot集成ShedLock實現(xiàn)分布式定時任務(wù)的示例代碼,需要的朋友可以參考下2024-12-12詳解Spring框架注解掃描開啟之配置細(xì)節(jié)
本篇文章主要介紹了詳解Spring框架注解掃描開啟之配置細(xì)節(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08