MyBatis 返回insert操作主键
应用场景 在向数据库插入数据时,需要保留插入数据的id,以便进行后续的update操作或者将id存入其他表作为外键。但是,在默认情况下,insert操作返回的是一个int值,它并非表示主键id,而是表示当前SQL语句影响的行数。
接下来,我们依次从options注解和SQL两个方面,了解MyBatis如何在使用MySQL和Oracle做insert插入操作时将返回的id绑定到对象中。
Mybatis的@Options注解
mybatis的@Options注解能够拿到对象自增的id的值,能够设置缓存时间,首先,创建一张用于测试的表instance。
CREATE TABLE instance (
instance_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键id',
infos VARCHAR(2048) NOT NULL DEFAULT '' COMMENT '消息',
create_time datetime COMMENT '创建时间',
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (instance_id)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT '实例表';
其中的instance_id是自增的主键。我希望通过dao层的接口插入的数据能够返回主键的id。接口代码如下:
@Insert("insert into instance (infos)"
+ " ("
+ " @{infos},"
+ " NOW()"
+ ")")
@Options(useGeneratedKeys = true, keyProperty = "instanceId", keyColumn = "instance_id")
int addInstance(Instance instanceDto);
@Options注解中默认设置的主键对应的字段名为id,而在instance表中,主键为instance_id,因此需要将keyProperty和keyColumn设置成我们想要的字段。这个示例的意思就是,从instance_id这个字段把数据放到传入对象instanceDto的instanceId成员变量里面。
在调用了插入方法之后,@Options注解会自动为表的主键字段设置自增的值,并把它赋值给作为入参的DTO,进而可以直接从这个对象中获取新生成记录的主键。接下来看下@Option注解的源码:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Options {
boolean useCache() default true;
boolean flushCache() default false;
ResultSetType resultSetType() default ResultSetType.FORWARD_ONLY;
StatementType statementType() default StatementType.PREPARED;
int fetchSize() default -1;
int timeout() default -1;
boolean useGeneratedKeys() default false;
String keyProperty() default "id";
String keyColumn() default "";
}
注解中的useCache还可以设置缓存相关的选项,useCache = true表示本次查询结果被缓存以提高下次查询速度,flushCache = false表示下次查询时不刷新缓存,timeout = 10000表示查询结果缓存10000秒。
在文献[2]中,Java API àMapper Annotations中可以找到英文原版介绍。
从执行insert SQL时返回主键ID
MySQL用法:
<insert id="insert" parameterType="com.test.Instance" keyProperty=" instanceId" useGeneratedKeys="true" >
上面配置中,“keyProperty”表示返回的instance_id要保存到对象的那个属性中,“useGeneratedKeys”表示主键为自增长模式。
MySQL中做以上配置就OK了,较为简单,不再赘述。下面分享Oracle中的用法。
<insert id="insert" parameterType="com.test.Instance ">
<selectKey resultType="Long" order="BEFORE" keyProperty="instanceId">
SELECT SEQ_USER.NEXTVAL as instanceId from DUAL
</selectKey>
insert into instance (instance_id, infos, create_time)
values (#{instanceId}, #{infos}, now())
</insert>
Oracle用法中,需要注意的是:由于Oracle没有自增长一说法,只有序列这种模仿自增的形式,所以不能再使用“useGeneratedKeys”属性,而是使用<selectKey>将ID获取并赋值到对象的属性中,insert插入操作时正常插入id。
参考文献
[1] https://www.cnblogs.com/sonofelice/p/6250203.html.
[2] http://www.mybatis.org/mybatis-3/index.html.
MyBatis 返回insert操作主键的更多相关文章
- Mybatis返回插入的主键
在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:如果业务层需要得到记录的主键时,可以通过配置的方式来完成这个功能 情景一:针对自增主键的表,在插入时不 ...
- MyBatis返回插入的主键ID(Mysql数据库)
1.Java代码: 1.1 entity类: User.java public class User { private int userId; private String userName; pr ...
- 杜绝网上压根没测过就乱写之 《oracle mybatis 返回自增主键 》
面试过好多人,包括自己也属于这么一个情况: 遇到问题直接去网上查,一般都可以查到解决方案.其中也包括一些基本的面试资料的答案. 其实有很多答案也都是正确的,但是还是存在一些压根就是胡乱抄来的答案,也不 ...
- Mybatis 返回插入的主键
业务中,会遇到这样的问题,就是感觉返回的主键,插入作为其他表的外键. 那么问题来了,如何去实现,其实方法比较简单,这里就是重点记录下,会出现的误区. 用自动生成sql工具的话,加上下面这句话 < ...
- mybatis返回自增主键踩坑记
背景 MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map ...
- 转mybatis返回自增主键,亲测
重点是获取对象的主键值而不是insert的返回值 Mybatis获取插入数据的主键时,返回值总是1xml里的写法 第一种方式 <insert id="insertLogin" ...
- 使用SQL脚本创建数据库,操作主键、外键与各种约束(MS SQL Server)
在实际开发中,可能很少人会手写sql脚本来操作数据库的种种.特别是微软的MS SQL Server数据库,它的SQL Server Management Studio对数据库的图形化操作极致简便,从而 ...
- 总结:String类型与Int类型的转换【实现插入操作主键自增】
1.String类型(此类型是数字格式的字符串类型)转换成Int类型 String str = "10000"; 转换成Int类型: int num = Integer.parse ...
- mybatis返回自增主键问题踩坑
1 <insert id="insert" keyProperty="id" useGeneratedKeys="true" par ...
随机推荐
- Android美丽的对话框项目sweet-alert-dialog
美丽的对话框 sweet-alert-dialog 项目地址: https://github.com/pedant/sweet-alert-dialog android原生的dialog太生硬了,之前 ...
- html5中的input和label写法与取值
demo 效果图如上 label是html5特有的,是定义 input 元素的标注.凡是input前面要有个label标识下,label和input真是一对好兄弟啊.<label> 标签的 ...
- Python实现无向图最短路径
一心想学习算法,很少去真正静下心来去研究,前几天趁着周末去了解了最短路径的资料,用python写了一个最短路径算法.算法是基于带权无向图去寻找两个点之间的最短路径,数据存储用邻接矩阵记录.首先画出一幅 ...
- Sql Server 数据类型与 C# 数据类型对照
Sql Server 数据类型与 C# 数据类型对照 已验证类型(Sql Server 2012 & Visual Studio 2013) Sql Server C# 简写 bigint S ...
- 总结一下搭建简单Web服务器的一些方法
使用nodejs+anywhere模块搭建静态文件服务器 anywhere随时随地将你的当前目录变成一个静态文件服务器的根目录. 安装npm install anywhere -g,然后进入任意目录在 ...
- [Laravel] 10 - WEB API : wrapper
前言 一.常用的解决方案 React 前端 + PHP (Laravel) 后端 Such as "some exposure to WEB API’s and/or RESTful“. 使 ...
- 理解AppDomain
在传统的 Win32的程序中,进程是独立的运行空间, 在一些大型系统中, 通常都是将系统中的核心功能分解出来用独立的进程来处理,一方面是为了能获得更高的系统性能.吞吐量 .另一方面是为了能隔离功能之间 ...
- android程序---->android多线程下载(二)
上篇我们讲到了android中下载的断点续传问题,今天我们开始学习下载的多线程问题.本次的多线程源码下载:androdi中多线程下载的实现代码.有关断点续传的问题,请参见博客:android程序--- ...
- VNC实现Windows远程访问Ubuntu 16.04(无需安装第三方桌面,直接使用自带远程工具)
本文主要是讲解如果理由VNC实现Windows远程访问Ubuntu 16.04,其实网上有很多类似教程,但是很多需要安装第三方桌面(xfce桌面等等),而且很多人不太喜欢安装第三方桌面,很多人像笔者一 ...
- URL中的空格
如果URL中带空格,在浏览器中可以显示,但是如果访问比如 UIImage 获取图片的时候就会出现BAD URL. 解决: NSString* urlText = @"70.84.58.40/ ...