在項目中遇到這樣的情況,新增一個角色,這個角色有某些權限,這兩個數據存在不同的表中,一個是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的源碼,提升一下自己。
