Mybatis「MySQL-Oracle」 中主键自动生成 <selectKey> 序列化

博客介绍了在数据库操作中获取新增主键的需求,指出数据库主键生成有int自增和varchar非自增两种。重点讲解了Mybatis中用selectKey获取新增主键,分别给出Oracle和MySQL的示例,还补充了order=befor、after在不同主键类型中的应用。

有时候我们不仅仅是通过返回 int 影响行数来确定数据是否插入成功就行了,因为我们总是会用到这个刚刚插入的自增主键,比如主子表入库,子表需要主表的 id,那这个时候我们再去数据库查就显得有点 low 了~

关于数据库中主键的生成无非就两种,一种是 int 类型的自增,一种是 varchar 类型的非自增(例如:UUID)。

在 Mybatis 中,提供了 selectKey 来帮我们获取新增的主键,同时通过 selectKey 可以很容易的实现自增还是非自增规则的需求。

下面从 Oracle 跟 MySQL 分别举例说明。
Oracle

<insert id="insertUserInfo" parameterType="club.sscai.entity.UserInfo">
    <selectKey keyProperty="id" resultType="java.lang.Integer" order="BEFORE">
        select SEQ_T_USER_INFO.NEXTVAL from dual
    </selectKey>
    insert into "T_USER_INFO"
    <trim prefix="(" suffix=")" suffixOverrides=",">
        ID,USER_NAME,PASSWORD,PHONE,STATUS,
        <if test="remark != null">
            REMARK,
        </if>
        CREATE_TIME,UPDATE_TIME,UPDATE_BY
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
        #{id,jdbcType=DECIMAL}, #{userName,jdbcType=VARCHAR},
        #{PASSWORD,jdbcType=VARCHAR},#{PHONE,jdbcType=VARCHAR},#{status,jdbcType=CHAR},
        <if test="remark != null">
            #{remark,jdbcType=VARCHAR},
        </if>
        #{createTime,jdbcType=TIMESTAMP},#{updateTime,jdbcType=TIMESTAMP}, #{updateBy,jdbcType=VARCHAR}
    </trim>
</insert>

如上代码主要是向 T_USER_INFO 表插入用户数据,parameterType 值传入的是实体对象,这里也可以是 map 或者是其他对象。

其中 的 keyProperty 值对应生成主键的字段,resultType 表示要返回的主键的类型,在这里我用的 Integer 类型,你也可以用 String,只要跟实体的字段对应即可。order 属性需要注意一下,不同于支持自增类型的 MySQL 等数据库,Oracle 需要设置设置为 after 才能取到正确的值,但是如果要从序列化中取值,则需要设置为 befor,否则会报错,我上边的代码是从序列中取值所以设置为 befor。

标签内的 SEQ_T_USER_INFO 表示该表的序列化,关于创建表序列化代码如下(SEQ_T_USER_INFO 名称随便起,尽量规范即可):

create sequence SEQ_T_USER_INFO
minvalue 1
maxvalue 9999999999999999999999999999
start with 1
increment by 1
cache 20;

字符串 uuid 类型非自增主键, selectKey 如下:

<selectKey keyProperty="id" resultType="java.lang.String" order="BEFORE">
    select sys_guid() from dual
</selectKey>

MySQL

<insert id="insertUserInfo" parameterType="club.sscai.entity.UserInfo" >
    <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.string">
        select uuid()
    </selectKey>
    insert into T_USER_INFO 
        (id, user_name, PASSWORD,PHONE,STATUS,REMARK,CREATE_TIME,UPDATE_TIME,UPDATE_BY)
    values 
    (#{id},#{userName},#{password},#{phone},#{status},省略...)
</insert>

上方是 MySQL 通过 select uuid() 就能得到 uuid 字符串,实现 UUID 字符串形式的主键生成。如果需要 int 类型则如下所示:

<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
    select LAST_INSERT_ID()
</selectKey>

至此,关于主键生成基本已经完事了,再额外补充关于 order = befor、after 的应用。

如果你使用的是 UUID() 这种形式的,建议选择 order = befor,而 order = after 更适合返回自增(int)类型的主键。

<think>好的,我现在需要回答用户关于MyBatis自动生成ID机制的问题。用户想知道在没有显式设置的情况下,MyBatis如何自动生成ID。首先,我需要回顾MyBatis的相关知识,特别是自动生成ID的方法。 根据用户提供的引用,特别是引用[1]引用[2],MyBatis可以通过配置生成器(MyBatis Generator)来自动生成实体类的注解,比如@Table、@Column@Id。此外,引用[2]提到使用工具类生成UUID作为ID,这可能是一种方式。但用户问的是不需要手动设置的情况,所以可能需要结合数据库的自主键MyBatis的配置。 首先,MyBatis Generator可以配置数据库表的主键为自,比如MySQL的AUTO_INCREMENT,这样在插入数据时,数据库自动生成ID。MyBatis的映射文件需要设置useGeneratedKeys为true,并指定keyProperty,这样插入操作后,生成的ID会自动填充到实体对象的对应属性中。 另外,使用UUID也是一种方式,但需要工具类生成,如引用[2]中的IDUtils,这可能需要在代码中显式调用,所以可能不属于“不需要手动设置”的情况。但如果是通过配置生成器自动生成带有UUID的代码,可能也算自动生成。 需要区分数据库程序生成的UUID两种方式。用户的问题可能更倾向于数据库的情况,这时MyBatis通过配置来获取生成的主键。此外,还要考虑不同的数据库,比如Oracle使用序列,这时候可能需要配置selectKey来获取下一个序列值。 在引用[3]中,提到了MyBatis Generator的插件化依赖问题,但可能ID生成机制关系不大。不过需要注意生成器配置是否正确,比如是否配置了主键的生成策略。 总结,MyBatis自动生成ID的机制主要依赖于数据库主键功能,结合MyBatis的useGeneratedKeys配置,或者在插入前通过selectKey元素获取序列值(如Oracle)。此外,还可以通过程序生成UUID,但这可能需要工具类辅助。 需要检查用户提供的引用是否有其他细节。引用[1]提到自动生成@Id注解,这可能对应数据库的自字段,而引用[2]是显式调用工具类生成ID,可能不算自动。因此,回答应重点放在数据库MyBatis配置上,以及生成器如何自动处理这些配置。 可能还需要解释MyBatis Generator在生成实体类映射文件时,如何根据数据库表的设置自动配置主键生成方式,比如对于自主键,生成对应的注解XML配置,使得插入时不需要手动设置ID。 最后,用户可能需要了解具体配置步骤,比如在generatorConfig.xml中设置生成的表,指定主键列,并确保数据库表有自属性。同时,回答应分点说明不同的机制,并给出示例配置代码,如XML中的useGeneratedKeyskeyProperty设置。</think>### MyBatis 自动生成 ID 的机制 MyBatis 在未显式设置 ID 时,主要通过以下两种机制实现自动生成 ID: --- #### 1. **基于数据库主键** - **适用场景**:数据库支持主键功能(如 MySQL 的 `AUTO_INCREMENT`、PostgreSQL 的 `SERIAL`)。 - **实现方式**: 1. **数据库表设计**:将主键字段设置为自。 ```sql CREATE TABLE user ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) ); ``` 2. **MyBatis 映射配置**:在 XML 映射文件中声明 `useGeneratedKeys` `keyProperty`,使插入操作后自动回填生成的 ID。 ```xml <insert id="insertUser" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user (name) VALUES (#{name}) </insert> ``` 插入数据时,无需手动设置 `id`,数据库生成的值会自动赋值给实体类的 `id` 字段[^1]。 --- #### 2. **通过程序生成唯一 ID** - **适用场景**:需要分布式唯一 ID(如 UUID)或数据库不支持自主键- **实现方式**: 1. **工具类生成 ID**:在 Java 代码中调用工具类生成唯一 ID(如 UUID),并通过 MyBatis 赋值。 ```java public class IDUtils { public static String getId() { return UUID.randomUUID().toString().replace("-", ""); } } ``` 2. **在业务逻辑中调用**: ```java User user = new User(); user.setId(IDUtils.getId()); // 自动生成唯一 ID userMapper.insertUser(user); ``` 此方法需在插入前显式调用工具类,但可通过代码封装实现自动化[^2]。 --- #### 3. **结合 MyBatis Generator 自动生成代码** - **配置生成器**:通过 `generatorConfig.xml` 配置自动生成实体类映射文件。 ```xml <table tableName="user"> <generatedKey column="id" sqlStatement="MYSQL" identity="true"/> </table> ``` - **生成结果**:实体类中会自动添加 `@Id` 注解,并在 XML 中配置自主键逻辑,减少手动编码[^1][^3]。 --- ### 常见问题示例 1. **如何选择自主键与 UUID?** -主键适合单机高并发插入,但分库分表时可能冲突; - UUID 保证全局唯一,但影响索引性能。 2. **Oracle 中如何实现自 ID?** 需通过序列触发器实现,MyBatis 中可使用 `<selectKey>` 获取序列值: ```xml <insert id="insertUser"> <selectKey keyProperty="id" resultType="int" order="BEFORE"> SELECT user_seq.NEXTVAL FROM DUAL </selectKey> INSERT INTO user (id, name) VALUES (#{id}, #{name}) </insert> ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值