MyBatis——insert并返回主键ID解决方案
問題描述?
添加記錄后獲取主鍵ID,這是一個很常見的需求,特別是在一次前端調用中需要插入多個表的場景。
除了添加單條記錄時獲取主鍵值,有時候可能需要獲取批量添加記錄時各記錄的主鍵值。
問題分析
暫無。
解決方案
MyBatis從3.3.1版本開始支持批量添加記錄并返回各記錄主鍵字段值。
添加單一記錄時返回主鍵ID
添加一條記錄時返回主鍵值,在xml映射器和接口映射器中都可以實現。
在映射器中配置獲取記錄主鍵值
XML映射器
在定義xml映射器時設置屬性useGeneratedKeys值為true,并分別指定屬性keyProperty和keyColumn為對應的數據庫記錄主鍵字段與Java對象的主鍵屬性。
<mapper namespace="org.chench.test.mybatis.mapper"><!-- 插入數據:返回記錄主鍵id值 --><insert id="insertOneTest" parameterType="org.chench.test.mybatis.model.Test" useGeneratedKeys="true" keyProperty="id" keyColumn="id" >insert into test(name,descr,url,create_time,update_time) values(#{name},#{descr},#{url},now(),now())</insert> </mapper>接口映射器
在接口映射器中通過注解@Options分別設置參數useGeneratedKeys,keyProperty,keyColumn值
// 返回主鍵字段id值 @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") @Insert("insert into test(name,descr,url,create_time,update_time) values(#{name},#{descr},#{url},now(),now())") Integer insertOneTest(Test test);獲取新添加記錄主鍵字段值
需要注意的是,在MyBatis中添加操作返回的是記錄數并非記錄主鍵id。因此,如果需要獲取新添加記錄的主鍵值,需要在執行添加操作之后,直接讀取Java對象的主鍵屬性。
Integer rows = sqlSession.getMapper(TestMapper.class).insertOneTest(test); System.out.println("rows = " + rows); // 添加操作返回記錄數 System.out.println("id = " + test.getId()); // 執行添加操作之后通過Java對象獲取主鍵屬性值添加批量記錄時返回主鍵ID
如果執行批量添加并返回各記錄主鍵字段值,只能在XML映射器中實現,在接口映射器中無法實現。
<!-- 批量添加數據,并返回主鍵字段 --> <insert id="insertBatchTest" useGeneratedKeys="true" keyProperty="id">INSERT INTO test(name,descr,url,create_time,update_time) VALUES<foreach collection="list" separator="," item="t">(#{t.name},#{t.descr},#{t.url},now(),now())</foreach> </insert>注:執行批量添加并返回記錄主鍵值的XML映射器配置,跟添加單條記錄時是一致的。不同的地方僅僅是使用了foreach元素構建批量添加語句。
實現原理
需要注意的是,不論在XML映射器還是在接口映射器中,添加記錄的主鍵值并非添加操作的返回值。
實際上,在MyBatis中執行添加操作時只會返回當前添加的記錄數。
package org.apache.ibatis.executor.statement; public class PreparedStatementHandler extends BaseStatementHandler {@Overridepublic int update(Statement statement) throws SQLException {PreparedStatement ps = (PreparedStatement) statement;// 真正執行添加操作的SQL語句ps.execute();int rows = ps.getUpdateCount();Object parameterObject = boundSql.getParameterObject();KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();// 在執行添加操作完畢之后,再處理記錄主鍵字段值keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);// 添加記錄時返回的是記錄數,而并非記錄的主鍵字段值return rows;} }MyBatis insert操作的時序圖:
跟蹤時序圖執行步驟可以看到,MyBatis最終是通過MySQL驅動程序獲取到了新添加的記錄主鍵值。
參考文章
https://www.cnblogs.com/nuccch/p/9067305.html
https://github.com/mybatis/mybatis-3/pull/350?Support insert multiple rows and write-back id.More about insert multipl...
https://www.zhihu.com/question/21153827?mybatis 批量插入如何返回每個條記錄的自生成主鍵?
https://blog.csdn.net/jiangeeq/article/details/55047116?Mybatis批量插入返回插入成功后的主鍵id
https://blog.csdn.net/top_code/article/details/52404345?MyBatis 3.3.1 批量插入多行回寫自增id
總結
以上是生活随笔為你收集整理的MyBatis——insert并返回主键ID解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring MVC——POST请求ap
- 下一篇: MASM + DOSBox——debug