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的源码,提升一下自己。
Mybatis+MSSql插入数据的同时并获取自增的ID的更多相关文章
- mybatis批量插入数据到oracle
mybatis 批量插入数据到oracle报 ”java.sql.SQLException: ORA-00933: SQL 命令未正确结束“ 错误解决方法 oracle批量插入使用 insert a ...
- Mybatis 批量插入数据
--mybatis 批量插入数据 --1.Oracle(需要测试下是否支持MySQL) < insert id ="insertBatch" parameterType=&q ...
- 【转载】MyBatis批量插入数据(insert)
介绍:MyBatis批量插入数据,原理就是在xml文件中添加 foreach 语句,然后MyBatis自动在values后面添加多个括号: XML文件如下: <?xml version=&quo ...
- mybatis的插入数据后的主键获取
为什么要在插入数据后获取主键:当有一个订单表和订单详情表,当插入订单表的数据后,需要在订单详情表插入该订单的具体购物情况,订单详情表需要的一个列是订单表的主键或者订单ID.(通俗讲:A表的主键是B表的 ...
- Mybatis:插入数据返回自增主键
使用Mybatis作为工具连接MySQL,要求在插入数据之后返回自增主键 一开始也很迷惑,Mybatis使用insert之后,成功返回的是1,失败会报错或返回0,主键去哪找来 后来知道Mybatis可 ...
- Mybatis + Mysql 插入数据时中文乱码问题
近日跟朋友一起建立一个项目,用的是spring+mybatis+mysql. 今天碰到一个mybatis向mysql中插入数据时,中文显示为'???'的问题,拿出来说下. 对于数据库操作中出现的中文乱 ...
- 【JDBC】向数据表插入数据时,自动获取生成的主键
数据表设计时,一般都会有一个主键(Key)(自己指定),有时也可以使用联合主键: 有许多数据库提供了隐藏列为表中的每行记录分配一个唯一键值(如:rowid): 当我们没有指定哪一列作为主键key时,数 ...
- mybatis批量插入数据
Mybatis在执行批量插入时,如果使用的是for循环逐一插入,那么可以正确返回主键id.如果使用动态sql的foreach循环,那么返回的主键id列表,可能为null,这让很多人感到困惑:本文将分析 ...
- mysql数据库新插入数据,需要立即获取最新插入的id
在MySQL中,使用auto_increment类型的id字段作为表的主键.通常的做法,是通过“select max(id) from tablename”的做法,但是显然这种做法需要考虑并发的情况, ...
随机推荐
- Maven设置snapshot无法在远程仓库下载的问题解决
检查步骤如下: 1.检查nexus是否纳入public版本中: 2.配置中是否启用snapshots功能.以下方法两种设置都可以,任选一个即可. 一种是在项目pom.xml使用: <reposi ...
- Linux命令之 file命令
该命令用来识别文件类型,也可用来辨别一些文件的编码格式.它是通过查看文件的头部信息来获取文件类型,而不是像Windows通过扩展名来确定文件类型的. 执行权限 :All User 指令所在路径:/us ...
- GSM模块_GPRS数据传输机制和原理
通信专业术语 BSS--基站子系统,通过无线接口与移动台直接联系,负责在一定区域内和移动台通信.(GSM) BTS--基站收发台,可以看作一复杂的无线调制器,BSS的主要部分,每个分配有若干信道.(G ...
- linux设置定制器自动执行任务
基本格式 : * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用*或者 */1表示 第2列表示小时1-23(0表示0点) 第3列表示日期1-31 ...
- 深入浅出 消息队列 ActiveMQ (转)
启动成功就可以访问管理员界面:http://localhost:8161/admin,默认用户名和密码admin/admin.如果你想修改用户名和密码的话,在conf/jetty-realm.prop ...
- 倍福TwinCAT(贝福Beckhoff)应用教程13.2 TwinCAT控制松下伺服 CS说明
虚拟仿真上,要注意仿真只是为了可视化,可以看到数据的变动是否和实际一致,所以Robot2D才是主要因素,虚拟仿真采集机器人的关节位置或者TCP位置来显示而已,为了测试一些别的算法,我们还可以在虚拟仿真 ...
- HDU 3917 Road constructions(最小割---最大权闭合)
题目地址:HDU 3917 这题简直神题意... 题目本身就非常难看懂不说..即使看懂了.也对这题意的逻辑感到无语...无论了.. 就依照那题意上说的做吧... 题意:给你n个城市,m个公司.若干条可 ...
- VLOOKUP多条件查找不使用辅助列
问题描述: 可能很多人在使用VLOOKUP的时候,对于多条件时,则会使用辅助列进行查找,那么不使用辅助列是否也可以呢? 答案是:必须可以. 问题处理: 1.使用辅助列 2.不使用辅助列的操作如下: 公 ...
- <转>多线程中的lua同步问题
转自 http://www.cnblogs.com/ghost240/p/3526185.html 最近写paintsnow::start时出现了一个非常麻烦的BUG,程序的Release版本大约每运 ...
- lucene 加速索引建立速度
加速 lucene 索引建立速度 ImproveIndexingSpeed