MyBatis框架——mybatis插入数据返回主键(mysql、oracle)

本文介绍了在MySQL和Oracle环境中,如何利用Mybatis在插入数据后返回自增主键和UUID主键的方法,包括LAST_INSERT_ID(), UUID(), 用户ID序列和SYS_GUID()的使用。

数据库中插入数据时,大多数情况都会使用自增列或者UUID做为主键。主键的值都是插入之前无法知道的,但很多情况下我们在插入数据后需要使用刚刚插入数据的主键,比如向两张关联表A、B中插入数据(A的主键是B的外键),向A表中插入数据之后,向B表中插入数据时需要用到A的主键。

  比如添加一个用户,同时返回插入用户后得到的用户id:

  1. /** * 添加用户信息 * @param user * @throws Exception */ public int insertUser(User user) throws Exception { SqlSession session=sqlSessionFactory.openSession(); session.insert("com.danny.mybatis.insertUser", user); session.commit(); return user.getUserId();//返回插入数据库后得到的用户id }

  这里总结一下mybatis插入数据时返回主键的4种情况:MySQL环境下主键自增、mysql环境下主键为uuid、mysql环境下主键自增、mysql环境下主键为uuid。

  以下全文均以User实体来举例说明,字段有userId、userName、sex、birthday、address 五个属性,其中userId有可能是int类型,也有可能是String类型。


数据库为mysql


主键为自增时(主键为数值类型且自增)

  利用mysql的LAST_INSERT_ID()方法获取插入记录的主键,select LAST_INSERT_ID()可以在插入数据后,查询并返回刚插入数据的主键(但是单独执行这条语句只会返回0)。

<insert id="insertUser" parameterType="com.danny.mybatis.po.User"> <selectKey keyProperty="userId" order="AFTER" resultType="java.lang.Integer"> select LAST_INSERT_ID() </selectKey> insert into T_USER(userName,birthday,sex,address) values (#{userName},#{birthday},#{sex},#{address}) </insert>

  parameterType:指定insert执行语句接收的参数类型为pojo(这里的user)。

  keyProperty:将查询到的主键值设置到parameterType指定对象的哪个属性。

  order:<selectKey> 标签内的sql语句相对于insert语句的执行顺序,AFTER表示select LAST_INSERT_ID() 这个语句将在insert语句之后执行。


主键为UUID时(主键必须为字符类型)

  使用mysql的方法UUID()方法获取随机的UUID作为主键,select UUID()可以在插入数据前,生成随机的UUID并通过keyProperty赋值给将要插入记录的主键。

<insert id="insertPerson" parameterType="com.danny.mybatis.po.User">
        <selectKey keyProperty="userId" order="BEFORE" resultType="java.lang.String">
            select UUID()
        </selectKey>
        insert into user(userId,userName,birthday,sex,address) values (#{id},#{userName},#{birthday},#{sex},#{address}) </insert>

  在上述代码中可以看到order 的属性值为BEFORE ,说明在插入之前就已经生成了UUID,并且已经把UUID赋值给user的id。


背 景数据库为oracle:

主键为自增时(主键为数值类型):

  在oracle中实现主键自增,需要先创建序列,相当于创建一个全局变量,用来存储对应表的主键的当前最大值(主键为数值类型时)。

  先为user表创建一个序列:

CREATE SEQUENCE USER_ID_SEQ

INCREMENT BY 1 -- 每次递增1

START WITH 1 -- 从1开始

MINVALUE 1 -- 最小值=1

NOCYCLE; -- 不循环

  利用USER_ID_SEQ.NEXTVAL 获得要插入数据的主键:

<insert id="insertUser" parameterType="com.danny.mybatis.po.User">
        <selectKey keyProperty="userId" order="BEFORE" resultType="java.lang.Integer"> select USER_ID_SEQ.NEXTVAL as userId from DUAL </selectKey> insert into T_USER(userId,userName,birthday,sex,address) values (#{userId},#{userName},#{birthday},#{sex},#{address}) </insert>


主键为UUID时

  用oracle自带的SYS_GUID()方法获得随机的GUID作为主键:

<insert id="insertUser" parameterType="com.danny.mybatis.po.User">
        <selectKey keyProperty="userId" order="BEFORE" resultType="java.lang.Integer"> select SYS_GUID() as userId from DUAL </selectKey> insert into T_USER(userId,userName,birthday,sex,address) values (#{userId},#{userName},#{birthday},#{sex},#{address}) </insert>
<think>嗯,用户想知道在MyBatis中如何获取插入数据后的自增ID。我之前学过一些MyBatis的知识,但得仔细想想具体步骤。首先,记得MyBatis有两种方法,一种是使用useGeneratedKeys和keyProperty配置,另一种是通过<selectKey>标签。不过用户提到generatedKey配置,可能指的是第一种方法。 首先,我需要确认数据库表的主键确实是自增的,比如MySQL的AUTO_INCREMENT或者PostgreSQL的SERIAL。然后,在MyBatis的Mapper XML文件中,插入语句的配置需要加上useGeneratedKeys="true",并指定keyProperty为实体类中对应的属性名,比如id。这样插入后,生成的ID会自动填充到实体对象的id属性中。 用户提供的引用内容里,引用3和4都提到了useGeneratedKeys和keyProperty的使用方法。例如,执行插入操作后,通过user.getId()就能拿到自增ID,而返回值int是受影响的行数,不是ID,这点引用2也提到了。所以需要确保用户知道应该从实体对象中获取ID,而不是方法的返回值。 另外,可能有特殊情况,比如数据库不支持自增主键,这时候可能需要用<selectKey>标签,比如在Oracle中使用序列。不过用户的问题可能主要集中在MySQL这类支持自增的数据库上。需要给出示例代码,包括XML配置和Java代码的调用方式,这样用户能更清楚。 还要注意事务管理,确保插入操作在事务内完成,否则可能获取不到ID。批量插入的情况可能更复杂,但用户的问题可能暂时不需要涉及,不过可以稍微提一下注意事项,如引用4里提到的。 总结步骤的话,应该是先配置Mapper XML,再在Java代码中通过实体对象获取ID。需要检查是否正确设置了keyProperty,以及实体类中的字段名是否匹配。常见的错误可能包括字段名拼写错误,或者忘记设置useGeneratedKeys,导致ID没有正确回填。 另外,用户可能遇到的误区是认为insert方法返回的是ID,但其实返回的是受影响行数,这点必须强调,如引用2中的例子。所以示例代码里要展示调用insert方法后,从对象中获取ID的正确方式。 最后,给出一个完整的示例,包括XML和Java代码,以及可能的测试输出,这样用户能对照自己的代码进行检查。同时,提醒一些注意事项,比如事务和批量处理的情况,确保用户在不同场景下都能正确应用。</think>### MyBatis获取插入数据自增ID的配置方法 在MyBatis中获取插入数据后的自增ID,需通过以下两种方式实现: --- #### 一、核心配置方法(推荐) 1. **XML映射文件配置** 在插入语句的`<insert>`标签中添加`useGeneratedKeys`和`keyProperty`属性: ```xml <insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user(name, age) VALUES(#{name}, #{age}) </insert> ``` - `useGeneratedKeys="true"`:启用数据库生成的主键获取功能[^3] - `keyProperty="id"`:将生成的主键值映射到实体类的`id`属性[^4] 2. **Java代码调用** ```java User user = new User(); user.setName("张三"); user.setAge(25); int rows = sqlSession.insert("com.example.mapper.UserMapper.insertUser", user); System.out.println("插入ID:" + user.getId()); // 直接通过对象获取 ``` --- #### 二、SELECT KEY方式(非自增场景) 适用于Oracle等使用序列生成主键数据库: ```xml <insert id="insertUser" parameterType="User"> <selectKey keyProperty="id" resultType="int" order="BEFORE"> SELECT user_seq.nextval FROM dual </selectKey> INSERT INTO user(id, name, age) VALUES(#{id}, #{name}, #{age}) </insert> ``` --- #### 三、注意事项 1. **事务管理** 必须确保插入操作在事务中完成,否则可能无法正确获取ID 2. **批量插入处理** 批量操作需使用`@Param`注解配合集合处理: ```xml <insert id="batchInsert" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user(name) VALUES <foreach collection="list" item="item" separator=","> (#{item.name}) </foreach> </insert> ``` 3. **常见错误** 若获取的ID始终为1,需检查是否误用了方法返回值(`int rows`),实际ID存储在参数对象中[^2] --- #### 四、完整示例 **实体类定义**: ```java public class User { private Integer id; // 必须与keyProperty匹配 private String name; // getters/setters } ``` **测试输出**: ```java User user = new User("李四", 30); mapper.insertUser(user); System.out.println(user.getId()); // 输出类似 2024 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值