应用场景 在向数据库插入数据时,需要保留插入数据的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操作主键的更多相关文章

  1. Mybatis返回插入的主键

    在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:如果业务层需要得到记录的主键时,可以通过配置的方式来完成这个功能 情景一:针对自增主键的表,在插入时不 ...

  2. MyBatis返回插入的主键ID(Mysql数据库)

    1.Java代码: 1.1 entity类: User.java public class User { private int userId; private String userName; pr ...

  3. 杜绝网上压根没测过就乱写之 《oracle mybatis 返回自增主键 》

    面试过好多人,包括自己也属于这么一个情况: 遇到问题直接去网上查,一般都可以查到解决方案.其中也包括一些基本的面试资料的答案. 其实有很多答案也都是正确的,但是还是存在一些压根就是胡乱抄来的答案,也不 ...

  4. Mybatis 返回插入的主键

    业务中,会遇到这样的问题,就是感觉返回的主键,插入作为其他表的外键. 那么问题来了,如何去实现,其实方法比较简单,这里就是重点记录下,会出现的误区. 用自动生成sql工具的话,加上下面这句话 < ...

  5. mybatis返回自增主键踩坑记

    背景 MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map ...

  6. 转mybatis返回自增主键,亲测

    重点是获取对象的主键值而不是insert的返回值 Mybatis获取插入数据的主键时,返回值总是1xml里的写法 第一种方式 <insert id="insertLogin" ...

  7. 使用SQL脚本创建数据库,操作主键、外键与各种约束(MS SQL Server)

    在实际开发中,可能很少人会手写sql脚本来操作数据库的种种.特别是微软的MS SQL Server数据库,它的SQL Server Management Studio对数据库的图形化操作极致简便,从而 ...

  8. 总结:String类型与Int类型的转换【实现插入操作主键自增】

    1.String类型(此类型是数字格式的字符串类型)转换成Int类型 String str = "10000"; 转换成Int类型: int num = Integer.parse ...

  9. mybatis返回自增主键问题踩坑

    1 <insert id="insert" keyProperty="id" useGeneratedKeys="true"
 par ...

随机推荐

  1. 回忆:NVelocity--基于.NET的模板引擎

    相关网址: http://www.castleproject.org/others/nvelocity/index.html http://www.castleproject.org/castle/d ...

  2. windows 注册表讲解

    注册表存储结构: 整个注册表内容主要由项(键).值(键值)构成.(通过regedit命令打开注册表) 5个根键: HKEY_CLASSES_ROOT    (缩写HKCR) HKEY_CURRENT_ ...

  3. Python终端自动补全

    在-目录下添加一个文件,名字为.pythonstartup.py #!/usr/bin/python # -*- coding: UTF-8 -*- import readline, rlcomple ...

  4. Apache重写规则由浅入深剖析.htaccess

    1..htaccess文件使用前提 .htaccess的主要作用就是实现url改写,也就是当浏览器通过url访问到服务器某个文件夹时,作为主人,我们可以来接待这个url,具体 地怎样接待它,就是此文件 ...

  5. 近5年常考Java面试题及答案整理(三)

    上一篇:近5年常考Java面试题及答案整理(二) 68.Java中如何实现序列化,有什么意义? 答:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化.可以对流化后的对象进行读写 ...

  6. [Node.js] 05 - Modules and Function

    一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码.JSON 或者编译过的C/C++ 扩展. 模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的. No ...

  7. 不用軟體解PPT密碼

    解PPT密碼的軟體很多,最好用的是advanced office password recovery pro,論壇裡有,不多說了~ 但是軟體有時候在解PPT密碼時多顯無力,現介紹不用軟體就能解pptx ...

  8. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】原创教程连载导读【连载完成,共二十九章】

    前言: 无数昼夜的来回轮替以后,这本<驱动篇I>终于编辑完毕了,笔者真的感动到连鼻涕也流下来.所谓驱动就是认识硬件,还有前期建模.虽然<驱动篇I>的硬件都是我们熟悉的老友记,例 ...

  9. HTML5实现本地JSON文件的读写

    参考: 使用HTML5来实现本地文件读取和写入  (FileReader读取json文件,FileSaver.js保存json文件) w3school <input>标签 FileRead ...

  10. ASP.NET Core Web API处理HttpResponseMessage类型返回值的问题

    在将我们的 web api 从 .NET Framework 迁移至 .net core(asp.net core 1.1)之后,遇到一个问题. 之前返回值类型为 HttpResponseMessag ...