映射插入语句 insert
标签包含如下属性。
id:命名空间中的唯一标识符,可用来代表这条语句。
parameterType:即将传入的参数的完全限定类名或别名。这个属性是可选的,因为 MyBatis 可以推断出传入语句的具体参数,因此不建议配置该属性。
flushCache:默认值为 true,任何时候只要该语句被调用,都会清空一级缓存和二级缓存。
timeout:设置在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。
statementType:对于 STATEMENT、PREPARED、CALLABLE,MyBatis 会分别使用对应的 Statement、PreparedStatement、CallableStatement,默认值为 PREPARED。
useGeneratedKeys:默认值为 false。如果设置为 true,MyBatis 会使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键。
keyProperty:MyBatis 通过 getGeneratedKeys 获取主键值后将要赋值的属性名。如果希望得到多个数据库自动生成的列,属性值也可以是以逗号分隔的属性名称列表。
keyColumn:仅对 INSERT 和 UPDATE 有用。通过生成的键值设置表中的列名,这个设置仅在某些数据库(如 PostgreSQL)中是必须的,当主键列不是表中的第一列时需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
databaseId:如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 的或匹配当前 databaseId 的语句。如果同时存在带 databaseId 和不带 databaseId 的语句,后者会被忽略。
接下来看一下接口中对应的方法int insert(Country row);
。该方法的 int 类型返回值并不是数据库返回的主键的值,而是 SQL 语句执行完后影响的行数,这个值和日志中的Updates:1
是一致的。如果是批量插入、批量更新、批量删除,这里的数字会是插入的数据行数、更新的数据行数、删除的数据行数。
返回自增后的主键值
useGeneratedKeys 设置为 true 时,MyBatis 会使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键。获得主键值后将其赋值给 keyProperty 配置的属性。当需要设置多个属性时,使用逗号隔开,这种情况下通常还需要设置 keyColumn 属性,按顺序指定数据库的列,这里列的值会和 keyProperty 配置的属性一一对应。
useGeneratedKeys 这种回写主键的方法只适用于支持主键自增的数据库。有些数据库(如 Oracle)不提供主键自增的功能,而是使用序列得到一个值,然后将这个值赋给 id,再将数据插入数据库。对于这种情况,可以采用另外一种方式:使用标签来获取主键的值,这种方式不仅适用于不提供主键自增功能的数据库,也适用于提供主键自增功能的数据库。
selectKey 标签的 keyColumn、keyProperty 和上面 useGeneratedKeys 的用法含义相同,这里的 resultType 用于设置返回值类型。
order 属性的设置和使用的数据库有关:
在 MySQL 数据库中,order 属性设置的值是 AFTER,因为当前记录的主键值在 insert 语句执行成功后才能获取到。
在 Oracle 数据库中,order 的值要设置为 BEFORE,这是因为 Oracle 中需要先从序列获取值,然后将值作为主键插入到数据库中。以下是 Oracle 数据库的用法示例:
注意:
Oracle 方式的 INSERT 语句中明确写出了 id 列和值#{id},因为执行 selectKey 中的语句后 id 就有值了,我们需要把这个序列值作为主键值插入到数据库中,所以必须指定 id 列,如果不指定这一列,数据库就会因为主键不能为空而抛出异常。
批量新增回写主键值
从 MyBatis 3.3.1 版本开始,MyBatis 开始支持批量新增回写主键值的功能,这个功能要求数据库主键值为自增类型,同时还要求该数据库提供的 JDBC 驱动可以支持返回批量插入的主键值(JDBC 提供了接口,但并不是所有数据库都完美实现了该接口),因此到目前为止,可以完美支持该功能的仅有 MySQL 数据库。
如果要在 MySQL 中实现批量插入返回自增主键值,只需要在原来代码基础上进行如下修改即可:
和单表一样,此处增加了 useGeneratedKeys 和 keyProperty 两个属性
Last updated