【Mybatis】-mybatis和Mysql返回插入的主键ID

本文介绍使用MyBatis在MySQL数据库中插入记录并返回主键的方法,包括自增主键和非自增主键两种情况。对于自增主键,通过LAST_INSERT_ID()函数获取;对于非自增主键,则采用uuid()函数生成。

需求:使用MyBatis往MySQL数据库中插入一条记录后,需要返回该条记录的主键值

自增主键返回

思路:
通过mysql函数获取到刚插入记录的自增主键:LAST_INSERT_ID()
执行过程:
执行insert提交之前自动生成一个自增主键,在insert之后调用此函数。
函数解释:
keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性
order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序
resultType:指定SELECT LAST_INSERT_ID()的结果类型

<!-- 添加用户 
    parameterType:指定输入 参数类型是pojo(包括 用户信息)
    #{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值
    -->
    <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">

        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            SELECT LAST_INSERT_ID()
        </selectKey>
        insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
        <!-- 
    </insert>

非自增主键返回

思路:
使用mysql的uuid()函数生成主键,需要修改表中id字段类型为string,长度设置成35位。
执行过程:
首先通过uuid()得到主键,将主键设置到user对象的id属性中,其次在insert执行时,从user对象中取出id属性值
执行uuid()语句顺序相对于insert语句之前执行。

<!-- 添加用户 
    parameterType:指定输入 参数类型是pojo(包括 用户信息)
    #{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值
    -->
    <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
        <!-- 
        将插入数据的主键返回,返回到user对象中
        使用mysql的uuid()生成主键
        执行过程:
        首先通过uuid()得到主键,将主键设置到user对象的id属性中
        其次在insert执行时,从user对象中取出id属性值
         -->
        <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
            SELECT uuid()
        </selectKey>
        insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address})   
    </insert>
<think>我们正在解决MyBatis-Plus使用XML进行批量插入返回主键ID的方法。 根据引用[1]引用[3],我们知道在MyBatis(以及MyBatis-Plus)中,插入单条记录并返回自增主键通常使用<selectKey>标签,并且使用LAST_INSERT_ID()(针对MySQL)来获取最后插入的自增ID。 但是,批量插入返回主键ID的情况有所不同。在MySQL中,使用批量插入时,LAST_INSERT_ID()只能返回第一个插入记录的自增ID,而不是所有插入记录的自增ID。 因此,我们需要采用不同的方法。在MyBatis中,我们可以通过设置useGeneratedKeyskeyProperty属性来实现批量插入返回主键ID。同样,在MyBatis-Plus中,我们也可以利用这个特性。 具体步骤: 1. 在XML映射文件中,编写批量插入语句,使用<insert>标签,并设置useGeneratedKeys="true"keyProperty="id"(这里的id主键字段名,如果实体类的主键属性名不是id,则写对应的属性名)。 2. 注意,对于批量插入,我们通常使用<foreach>标签来遍历集合。 3. 在调用插入方法后,传入的实体对象列表中的每个实体对象的主键属性就会被自动赋值为新生成的主键值。 但是,需要注意的是: - MySQL的JDBC驱动要求连接属性allowMultiQueries=true(在连接字符串中设置),以便支持一次执行多条SQL语句(如果使用foreach动态生成多个插入值,则生成的SQL是一条INSERT语句包含多个VALUES,这不需要多条语句,所以不需要设置allowMultiQueries;而如果foreach中分隔符是分号,则需要设置,但批量插入通常是一条INSERT语句,所以一般不需要)。 - 另外,确保数据库表的主键是自增的。 示例代码: 假设我们有一个实体类User,主键属性名为id,表为user表,有usernamepassword字段。 在XML中: ```xml <insert id="insertBatch" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user (username, password) VALUES <foreach collection="list" item="item" separator=","> (#{item.username}, #{item.password}) </foreach> </insert> ``` 然后在Mapper接口中定义方法: ```java int insertBatch(@Param("list") List<User> userList); ``` 调用该方法后,传入的userList中的每个User对象的id属性就会被自动赋值。 注意:使用MyBatis-Plus时,我们也可以使用其自带的Service方法,例如saveBatch,但是默认情况下,saveBatch方法不会返回主键值。因此,如果使用MyBatis-Plus的Service层,我们可以这样: 1. 使用上面的XML方式自定义一个批量插入方法。 2. 或者,使用MyBatis-Plus的SQL注入器,但比较复杂。 所以,通常我们采用自定义XML的方式。 另外,引用[3]中提到了单条插入使用<selectKey>,但批量插入不适用。 总结:使用XML配置批量插入返回主键的关键点: - 在<insert>标签上设置useGeneratedKeys="true"keyProperty(这里keyProperty设置为实体类中主键对应的属性名,如果是一个列表,则每个元素的主键属性都会被赋值)。 - 使用foreach标签构建批量插入语句。 注意:keyProperty的值应该是每个元素对象中的主键属性名。例如,如果传入的是List<User>,那么User对象中主键属性名为id,则keyProperty="id";如果传入的是List<Person>,而Person的主键属性名为personId,则keyProperty="personId"。 但是,在批量插入时,我们通常传入一个列表,所以我们需要在keyProperty中指定列表中每个元素的主键属性。因此,如果列表中的元素有多个属性,我们需要明确指定每个元素的主键属性名。 另外,对于非自增主键(如UUID),则不能使用此方法,需要另外处理。 因此,针对用户的需求,我们给出以下步骤: 1. 在Mapper接口中定义批量插入方法,参数为List。 2. 在对应的XML映射文件中,使用<insert>标签,设置useGeneratedKeyskeyProperty,编写批量插入SQL。 3. 调用该方法后,检查传入列表中的每个对象,其主键属性已经被赋值。 示例代码(详细): Mapper接口: ```java public interface UserMapper extends BaseMapper<User> { int insertBatch(@Param("list") List<User> userList); } ``` XML映射文件(UserMapper.xml): ```xml <insert id="insertBatch" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user (username, password) VALUES <foreach collection="list" item="item" index="index" separator=","> (#{item.username}, #{item.password}) </foreach> </insert> ``` 调用代码: ```java List<User> userList = new ArrayList<>(); // 添加多个User对象到userList userMapper.insertBatch(userList); // 此时,userList中的每个User对象的id已经被设置为主键值 ``` 这样,批量插入后,每个User对象的id属性就包含了数据库生成的自增主键值。 注意:如果数据库支持多行插入(如MySQL),那么这种方法有效。对于不支持多行插入数据库(如Oracle),需要使用其他方式,例如使用中间表或者分批插入。 另外,MyBatis-Plus自带的saveBatch方法默认不会返回主键值。如果不想用XML,也可以考虑使用MyBatis-Plus的SQL注入器扩展,但相对复杂。因此,使用XML映射文件是较为通用简单的方法。 所以,用户的问题可以通过上述方式解决。 生成相关问题: 1. 在MyBatis-Plus中,除了使用XML配置,还有其他方法实现批量插入返回主键ID吗? 2. 批量插入时,如果主键不是自增的,如何返回主键ID? 3. 使用MyBatis-Plus的saveBatch方法如何让其返回主键ID? </think> ### MyBatis-Plus使用XML批量插入返回主键ID的方法 在MyBatis-Plus中,通过XML实现批量插入返回主键ID的核心是**联合使用`useGeneratedKeys``keyProperty`属性**,结合动态SQL的`<foreach>`标签。以下是具体实现步骤: --- #### 1. **Mapper接口定义** ```java public interface UserMapper extends BaseMapper<User> { int batchInsertUsers(@Param("list") List<User> userList); } ``` #### 2. **XML映射文件配置** ```xml <insert id="batchInsertUsers" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user (name, age, email) VALUES <foreach collection="list" item="item" separator=","> (#{item.name}, #{item.age}, #{item.email}) </foreach> </insert> ``` **关键参数说明**: - `useGeneratedKeys="true"`:启用数据库生成的主键 - `keyProperty="id"`:将主键值注入到实体类的`id`属性(属性名需与实体类字段一致) - `<foreach>`:动态拼接批量插入的VALUES列表 --- #### 3. **Service层调用** ```java @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> { public void batchInsertWithReturnIds(List<User> userList) { userMapper.batchInsertUsers(userList); // 此时userList中每个对象的id已被自动注入 userList.forEach(user -> System.out.println("生成的主键ID: " + user.getId())); } } ``` --- ### 🔧 技术要点解析 1. **数据库兼容性**: - MySQL/SQLite:直接使用上述配置 - PostgreSQL:需指定`keyColumn="id"`,且主键需是`SERIAL/BIGSERIAL`类型 - Oracle:需配合序列(Sequence)`<selectKey>`(不支持直接返回主键) 2. **批量插入限制**: - 单次批量操作建议不超过1000条(避免SQL过长) - 超大批量需分批次插入(例如每批500条) 3. **常见错误排查**: - 确保实体类主键字段有`@TableId`注解 - 检查数据库表主键是否为自增(AUTO_INCREMENT) - 确认JDBC连接串含`allowMultiQueries=true`(部分驱动需要) --- ### 💡 对比MyBatis-Plus内置方法 | 方法 | 是否返回主键 | 批量支持 | |------|-------------|----------| | `saveBatch()` | ❌ 不返回 | ✔️ 支持 | | XML自定义批量插入 | ✔️ 返回 | ✔️ 支持 | | 注解`@Insert` | 仅单条返回 | ❌ 不支持 | > 因此**XML是实现批量返回主键的最优方案**[^1][^3]。 --- ### 示例场景 插入3条数据并打印主键: ```java List<User> users = Arrays.asList( new User(null, "Tom", 20, "tom@test.com"), new User(null, "Jerry", 22, "jerry@test.com"), new User(null, "Spike", 25, "spike@test.com") ); batchInsertWithReturnIds(users); // 输出结果示例: // 生成的主键ID: 10086 // 生成的主键ID: 10087 // 生成的主键ID: 10088 ``` ---
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子松的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值