文概览:为了介绍Mybatis获取自增主键,分别介绍了通过MysqlJDbc两种方式。

1 Mysql实现

1.1 方式1  max(id)

最简单的方法是通过“select max(id) from tablename”的做法,但是显然这种做法需要考虑并发的情况,需要在事务中对主表加以“X,待获得max(id)的值以后,再解锁。

1.2 方式2 last_insert_id()

LAST_INSERT_ID是基于Connection的,只要每个线程都使用独立的 Connection对象,LAST_INSERT_ID函数将返回该ConnectionAUTO_INCREMENT列最新的insert or update 操作生成的第一个recordID

1.3 方式3 select @@IDENTITY

这个方式和LAST_INSERT_ID()效果是一样的,所以二者选一个就可以

2 JDBC方式

2.1 getGeneratedKeys()

1. 介绍

使用举例

1. JDBC的java.sql.Statement#getGeneratedKeys()的方法与last_insert_id()方法区别:

At times, it can be tricky to use the SELECT LAST_INSERT_ID() query, as that function’s value is scoped to a connection. So, if some other query happens on the same connection, the value is overwritten.

On the other hand, the getGeneratedKeys() method is scoped by the Statement instance, so it can be used even if other queries happen on the same connection, but not on the same Statement instance.

这段话其实就是:对于一个连接Connection,产生两个Statement:statement1和statement2,这两个Statement执行分表别执行插入操作,那么"select last_insert_id"的值是这个连接对应的最新插入的id,但是statement1.getGeneratedKeys()和statement2.getGeneratedKeys值是分别是对应的statement插入时对应的值.

参考:http://dev.mysql.com/doc/connector-j/en/connector-j-usagenotes-last-insert-id.html

3 Mybatis方式

3.1 方式1 getGeneratedKeys属性

1、getGeneratedKeys是<insert>和<update>节点的属性,如<insert id=”” parameterType=”” useGeneratedKeys=”true”>方法。这个属性和JDBC的java.sql.Statement的getGeneratedKeys()作用是一样的。其他属性还有keyProperty和keyColumn两种属性:

  • useGeneratedKeys
  • keyProperty  指定获取的结果值,赋值给参数对象中相应的属性成员。
  • keyColumn  显示的指定数据表的那个列是自增列,这个一般情况下不设置

2、参数类型是对象类型

在Dao中insert实现时,parameterType为对象类型时,如下

mybatis对于插入操作设置插入后id,QsightSyncTreeLogEntity中id就变为插入后的id。对应的mapper.xml为:

3. 参数不是对象类型

这种情况下获取增量主键的方法是:将参数设置成map类型

(1)举例,如在Dao中insert实现时,如下

对应的mapper.xml文件为:

此时如果要获取自增id,dao就需要改写为

此时就可以通过map.get(“id”)就就可以读取自增id了

(2)参数不能设置为基本类型的原因,如下

这里不能通过如下方法来做

这是引入举例如这样一个函数

我们执行如下操作

此时执行记过仍然为

num=1,str=kk

所以参数设置为基本类型不能把keyProperty的值传递出来。

3.2 方式2  selectkey

1、slectKey的两个作用:

  • 作用1:mybatis通过<selectkey>方法来实现mysql的”select select last_insert_id()”和”select @@IDENTITY”对应.
  • 作用2:对于不支持自动生成类型的数据库或可能不支持自动生成主键 JDBC 驱动来说,MyBatis 使用这种方法来生成主键。

2、说明keyProperty、keyColumn、order by 、resultType属性

  • keyProperty  指定获取的结果值,赋值给参数对象中相应的属性成员。
  • keyColumn 显示的指定数据表的那个列是自增列,这个一般情况下不设置
  • order by  如果设置为 BEFORE,那么它会首先选择主键,设置 keyProperty 然后执行插入语句。如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 元素 – 这和Oracle 的数据库相似,在插入语句内部可能有嵌入索引调用。所以为了获取插入新数据之后的id,那么这个属性应该设置为AFTER。
  • resultType

2、使用<selectKey>来实现mysql的select @@IDENTITY

3、使用<selectKey>来实现mysql的select last_insert_id()

3.3 两种方式的总结

1、相同点

 无论useGeneratedKeys还是<selectKey>获取自增主键之后,都是通过keyProperty输出.所以需要在dao定义的insert接口函数中有一个参数来接受这个值

  • 当参数是一个对象类型时   直接将keyProperty的标注的字段的值设置为自增主键的值
  • 当参数不是对象类型时   将参数类型修改为map类型。

2、不同点

优先使用useGeneratedKeys.当对于不支持自动生成类型的数据库或可能不支持自动生成主键 JDBC 驱动,MyBatis才引入<selectKey> 这种方法来生成主键.对于mysql而言,这个数据库具有主键自增的功能,所以直接使用useGeneratedKeys就可以了.而且<selectKey>会执行效率就没有 getGeneratedKeys 高。所以,在”数据库不支持自动生成主键时”的场景中才会想到使用<selectKey>

(全文完)

 

分类&标签

发表评论

电子邮件地址不会被公开。 必填项已用*标注