Mybatis+MSSql插入數據的同時並獲取自增的ID


在項目中遇到這樣的情況,新增一個角色,這個角色有某些權限,這兩個數據存在不同的表中,一個是sys_role,另外一個是sys_role_permission表,注意,現在的邏輯是這樣的

1,在表sys_user中新增一個角色,里面存放角色id和角色名稱,

2,從1中獲取新增的角色id,然后講這個角色對應的權限存放在sys_role_permission中。

本項目使用的是mybatis+ms sql 2008,然后我在網上開始找資料,以及在api文檔中找資料,發現資料幾乎是mysql的,而針對ms sqlserver的比較少。還好我試了一晚上終於出來結果了,並且對api文檔的介紹有了更進一步的認識

首先,貼代碼,然后講解

    <insert id="insertRole">
        BEGIN
        INSERT INTO [sys_role]([role_name],[available]) VALUES(#{role.roleName},1);
        <selectKey resultType="int" keyProperty="role_id" order="BEFORE">
            -- SELECT MAX(role_id) as id FROM [sys_role];
            SELECT IDENT_CURRENT('sys_role')+1
        </selectKey>
        <foreach item="item" index="index" collection="list">
            insert into sys_role_permission(role_id,permission_id) VALUES (#{role_id}, #{item});
        </foreach>
        END
    </insert>

注意,官方文檔關於order的注釋:

這可以被設置為 BEFORE 或 AFTER。如果設置為 BEFORE,那么它會首先選擇主鍵,設置 keyProperty 然后執行插入語句。如果設置為 AFTER,那么先執行插入語句,然后是 selectKey 元素 - 這和像 Oracle 的數據庫相似,在插入語句內部可能有嵌入索引調用。

怎么理解這個“先執行插入語句”?

上面的mapper.xml文件中,有兩部插入操作

1,給sys_role插入角色信息

2,給sys_role_permission中插入角色權限對應關系

所以,剛開始我理解的先執行插入語句是這樣的:在執行selectKey下面的那個insert語句前執行的,所以,我剛開始設置的order="after",這樣一直出現這樣的錯誤

2017-02-20 23:19:32,757 [main] DEBUG [com.unisits.zngkpt.common.userprivrman.mapper.SysRoleDao.insertRole] - ==>  Preparing: BEGIN INSERT INTO [sys_role]([role_name],[available]) VALUES(?,1); insert into sys_role_permission(role_id,permission_id) VALUES (?, ?); insert into sys_role_permission(role_id,permission_id) VALUES (?, ?); END 
  2017-02-20 23:19:32,813 [main] DEBUG [com.unisits.zngkpt.common.userprivrman.mapper.SysRoleDao.insertRole] - ==> Parameters: test1(String), null, 10(Integer), null, 11(Integer)
  2017-02-20 23:19:32,820 [main] DEBUG [com.unisits.zngkpt.common.userprivrman.mapper.SysRoleDao.insertRole] - <==    Updates: 1
 2017-02-20 23:19:32,822 [main] DEBUG [com.unisits.zngkpt.common.userprivrman.mapper.SysRoleDao.insertRole!selectKey] - ==>  Preparing: -- SELECT MAX(role_id) as id FROM [sys_role]; SELECT IDENT_CURRENT('sys_role')+1 
  2017-02-20 23:19:32,822 [main] DEBUG [com.unisits.zngkpt.common.userprivrman.mapper.SysRoleDao.insertRole!selectKey] - ==> Parameters: 
  2017-02-20 23:19:32,847 [main] DEBUG [com.unisits.zngkpt.common.userprivrman.mapper.SysRoleDao.insertRole!selectKey] - <==      Total: 1

看看,先看執行順序啊:1,先執行所有的insert語句,而第二步中的insert語句的role_id為空,也就是說沒有這個值,為什么呢?很明顯,給sys_role_permission的role_id參數設置值的selectKey並沒有執行,所以,到這里你就明白了,“先執行插入語句”意思就是說先執行所有的插入語句,然后執行selectKey里面的語句

那么,真的是這樣么?那我把order該為“BEFORE”呢,運行結果如下:

  2017-02-20 23:24:36,036 [main] DEBUG [com.unisits.zngkpt.common.userprivrman.mapper.SysRoleDao.insertRole!selectKey] - ==>  Preparing: -- SELECT MAX(role_id) as id FROM [sys_role]; SELECT IDENT_CURRENT('sys_role')+1 
  2017-02-20 23:24:36,085 [main] DEBUG [com.unisits.zngkpt.common.userprivrman.mapper.SysRoleDao.insertRole!selectKey] - ==> Parameters: 
  2017-02-20 23:24:36,119 [main] DEBUG [com.unisits.zngkpt.common.userprivrman.mapper.SysRoleDao.insertRole!selectKey] - <==      Total: 1
 2017-02-20 23:24:36,168 [main] DEBUG [com.unisits.zngkpt.common.userprivrman.mapper.SysRoleDao.insertRole] - ==>  Preparing: BEGIN INSERT INTO [sys_role]([role_name],[available]) VALUES(?,1); insert into sys_role_permission(role_id,permission_id) VALUES (?, ?); insert into sys_role_permission(role_id,permission_id) VALUES (?, ?); END 
  2017-02-20 23:24:36,186 [main] DEBUG [com.unisits.zngkpt.common.userprivrman.mapper.SysRoleDao.insertRole] - ==> Parameters: test1(String), 31(Integer), 10(Integer), 31(Integer), 11(Integer)
  2017-02-20 23:24:36,193 [main] DEBUG [com.unisits.zngkpt.common.userprivrman.mapper.SysRoleDao.insertRole] - <==    Updates: 1

看看上面的結果,是不是說明上面的假設成立

綜上,對mybatis selectKey中的order的正確理解是

before是在所有的insert操作前執行

after是在所有的insert操作后執行

好了,上面是自己的一些見解。主要網上針對mybatis+mssql的資料並不多。只能邊做編總結了。

還有,以后喲時間來琢磨琢磨mybatis的源碼,提升一下自己。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM