Mybatis——<selectKey>生成主键/获取插入数据主键

本文介绍在不支持自动生成主键的数据库或JDBC驱动中如何利用MyBatis实现主键值的生成。通过selectKey元素可以灵活地设置主键值,使得Java代码更加简洁。
  1. 对于不支持自动生成类型的数据库或可能不支持自动生成主键 JDBC 驱动来说,MyBatis 有另外一种方法来生成主键
  2. 获取插入数据的主键值

这里有一个简单(甚至很傻)的示例,它可以生成一个随机 ID(你最好不要这么做,但这里展示了 MyBatis 处理问题的灵活性及其所关心的广度):(从另一个角度来看,这种写法获取到了本条插入数据的主键ID)

<insert id="insertAuthor">
  <selectKey keyProperty="id" resultType="int" order="BEFORE">
    select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
  </selectKey>
  insert into Author
    (id, username, password, email,bio, favourite_section)
  values
    (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})
</insert>

在上面的示例中,selectKey 元素将会首先运行,Author 的 id 会被设置,然后插入语句会被调用。这给你了一个和数据库中来处理自动生成的主键类似的行为,避免了使 Java 代码变得复杂。
selectKey 元素描述如下:

<selectKey
  keyProperty="id"
  resultType="int"
  order="BEFORE"
  statementType="PREPARED">
属性描述
keyPropertyselectKey 语句结果应该被设置的目标属性。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
keyColumn匹配属性的返回结果集中的列名称。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
resultType结果的类型。MyBatis 通常可以推算出来,但是为了更加确定写上也不会有什么问题。MyBatis 允许任何简单类型用作主键的类型,包括字符串。如果希望作用于多个生成的列,则可以使用一个包含期望属性的 Object 或一个 Map。
order这可以被设置为 BEFORE 或 AFTER。如果设置为 BEFORE,那么它会首先选择主键,设置 keyProperty 然后执行插入语句。如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 元素 - 这和像 Oracle 的数据库相似,在插入语句内部可能有嵌入索引调用。
statementType与前面相同,MyBatis 支持 STATEMENT,PREPARED 和 CALLABLE 语句的映射类型,分别代表 PreparedStatement 和 CallableStatement 类型。
### MyBatis主键生成策略 #### JDBC 方式返回主键自增值 当使用 MySQL 或其他支持自动增长列的数据库时,可以利用 `useGeneratedKeys` 属性让 MyBatis 获取数据生成主键值。这通常用于表中有 AUTO_INCREMENT 类型的字段情况。 ```xml <insert id="insertUser" useGeneratedKeys="true" keyProperty="id"> INSERT INTO users(name, age) VALUES (#{name}, #{age}) </insert> ``` 此配置使得执行插入操作后,MyBatis 将会把新产生的 ID 赋给 Java 对象对应的属性[^1]。 #### 自定义 SQL 表达式获取主键 对于那些不支持自动增量特性的数据库,或者希望手动控制主键分配的情况,则可通过 `<selectKey>` 元素来自定义主键生成逻辑: ```xml <insert id="insertBlogPostWithSelectKey"> <selectKey resultType="int" keyProperty="blogId" order="BEFORE"> SELECT seq_blog.nextval FROM DUAL </selectKey> insert into Blog(id,title,content) values(#{blogId},#{title},#{content}); </insert> ``` 这里展示了如何通过 Oracle 序列对象来预先设定即将插入记录的主键值[^4]。 #### 使用 UUID 作为唯一标识符 除了依赖于底层数据库机制外,还可以采用应用程序层面的方法生成全局唯一的主键,比如基于时间戳和随机数组合而成的字符串形式——UUID: ```java public class User { private String id; public void setId() { this.id = java.util.UUID.randomUUID().toString(); } } ``` 这种方式适用于分布式环境中跨多个实例部署的应用程序场景下保持数据一致性需求[^2]。 #### 雪花算法(Snowflake Algorithm) 最后,在某些框架扩展版本如 MyBatis Plus 中,默认采用了 Twitter 开源的 SnowFlake 算法实现高效并发环境下的唯一ID生产器。该方案综合考虑了机器编号、数据中心编码等因素以确保最终产出的结果既有序又不会重复[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值