在项目中遇到这样的情况,新增一个角色,这个角色有某些权限,这两个数据存在不同的表中,一个是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的源码,提升一下自己。

最新文章

  1. 挖一挖C#中那些我们不常用的东西之系列(5)——FlagAttribute
  2. 什么是viewport,为什么需要viewport
  3. bug提交模板
  4. JavaScript Emoji 表情库_js 类似于qq微信的表情库
  5. Hadoop-1.2.1 安装步骤小结(ubuntu)
  6. iOS开发-NSURLSession详解
  7. dialog横竖屏切换时消失的解决方法
  8. cocos2d-html5版日历组件
  9. ORACLE执行计划 explain说明
  10. Python脚本控制的WebDriver 常用操作 &lt;二十一&gt; 执行JS
  11. table 表头固定
  12. 使用fixed制作浮动广告(注意:解决闪屏问题,但适用于高版本浏览器,低版本的浏览器不适用)
  13. springBoot系列教程02:mongodb的集成及使用
  14. Socket用线程池处理服务
  15. codeforces347B
  16. linux虚拟机配置上网(静态IP)和配置tomcat服务环境
  17. 数据库连接不关闭造成的问题以及RowSet的使用
  18. memcache的下载与安装
  19. C#在Win10与非Win10 Windows系统鼠标滚动编程的一点区别。
  20. SpringBoot热部署:spring-boot-devtools在Idea中热部署方法

热门文章

  1. SQL server 2008 安装问题解决 转
  2. Java使用纯真IP库获取IP对应省份和城市
  3. ubuntu查看系统版本
  4. Windows下搭建Solr环境
  5. FIS 配置小诀窍
  6. Node.js 使用爬虫批量下载网络图片到本地
  7. 手机号码月消费档次API
  8. POJ1274:The Perfect Stall(二分图最大匹配 匈牙利算法)
  9. android 开机自启动的几种方法,监听不到RECEIVE_BOOT_COMPLETED的处理办法
  10. C/C++ linux下光标定位和清屏函数