在项目中的表格主键我们大多使用自增的字段id来表示,但是不同的数据库对自增这个问题的解决方式是不同的,如MySql本身是支持自增的,对字段添加auto_increment配置即可,但是Oracle并不支持自增,必须借助序列来解决,而selectKey就是帮助MyBatis来解决这个问题的。那我们来看下MyBatis在插入数据的时候是如何解决主键自增问题的。
看下Mybatis中insert语句与主键有关的两个属性配置:如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server 数据库),那么你可以设置 useGeneratedKeys=”true”,而且设置 keyProperty 到你已经做好的目标属性上。例如在MySql中创建表格User,设置id字段为自增:
CREATE TABLE `user` (
`Id` int(11) NOT NULL auto_increment,
`account` varchar(25) default NULL,
`password` varchar(25) default NULL,
`username` varchar(25) default NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
那么插入数据的配置语句可以修改为:
useGeneratedKeys=”true” keyProperty=”id”>
insert into user (account,username,password)
values (#{account},#{username},#{password})
MyBatis 有另外一种方法来处理数据库不支持自动生成类型,或者可能 JDBC 驱动不支持自动生成主键时的主键生成问题。 如Oracle中不支持关键字auto_increment,所以不能设置字段为自增,那么在插入数据的时候不能自动生成主键值,就需要使用selectKey,语句如下:
select idseq.nextVal from dual
insert into User
(id, account,username, password) values
(#{id}, #{account},#{username}, #{password})
在上面的示例中,
selectKey 元素将会首先运行, User的 id 会被设置,然后插入语句会被调用。这给你了一个简单的行为在你的数据库中来处理自动生成的主键,而不需要使你的 Java 代码变得复杂。
selectKey 元素描述如下:
keyProperty="id"
resultType="int"
order="BEFORE"
statementType="PREPARED">
来个实际的例子验证下:
Oralce数据库中有表格t_user和序列idseq,表格的数据如下:
idseq的当前值是4,状态如下:
user的映射文件中有如下配置:
当我们执行如下代码后,看下数据的变化:
代码中在执行addUser之前没有设置user对象的id属性,配置中通过执行selectKey会为user对象设置id属性的值,所以看到控制台输出的id分别为:
而数据库中也会增加相应的值,表格数据变化如下: