Mybatis执行insert/update获取主键id

本文介绍了如何在Mybatis中通过update自动获取id、使用自增id、selectKey标签设置返回值以及在insert中指定keyProperty来获取主键ID。适合掌握Mybatis操作时需要获取最新生成ID的开发者。

问题: Mybatis执行insert/update后如何获得主键id

Mybatis执行insert/update操作时,默认返回的是插入成功的个数,如果想要获得主键id,有以下几种方法

update默认返回id

在mybatis的update操作中,如果传入的参数有id或者传入的参数有id字段,那么更新成功后,会自动的将id赋给传入的对应id字段。在执行完成后,再调用变量就可以获取id的值了

@Data
classs xxDto {
	private Long id;
    ·····
}

<update id="xxx" parameterType="xxDto">
</update>

执行完update后,通过xxDto.getId()就能获取到id

insert使用自增id

在select传入的参数中加入 id 字段,或者传入实体类中加入id字段

在select标签中使用加入自增id配置,useGeneratedKeys="true" keyProperty="id"

这样在插入后可以将id的值赋值给传进来的 id参数

<insert id="xxxx" useGeneratedKeys="true" keyProperty="id" parameterType="xxxx">
		xxxxx
</insert>

这种方法类似update

selectKey标签更改返回值

selectKey标签可以在insert和update中使用

  • keyProperty 对应Java实体类中充当主键的属性名,跟数据库的主键对应

  • order 取值 AFTER 或者 BEFORE。如上例子所述,AFTER 表示在insert执行之后执行 SELECT LAST_INSERT_ID() ,多用获取自增主键;BEFORE 表示在insert执行之前执行select uuid(),适合那种主键不是自增的情况,实现自定义主键。

  • resultType:主键类型

    insert之后返回主键id作为返回值

<insert id="xxx">
	.....
    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
        SELECT LAST_INSERT_ID()
    </selectKey>
</insert>
<think>好的,我现在需要帮助用户了解MyBatisinsertOrUpdate的用法,并提供示例。用户已经给出了一些相关的引用内容,我需要结合这些引用来构建回答。 首先,用户的问题是关于MyBatisinsertOrUpdate操作,也就是通常所说的“upsert”(更新或插入)。我需要确定在MyBatis中如何实现这个功能。根据用户的引用内容,特别是引用3和4,提到了批量插入和更新,但用户现在需要的是单个记录的存在时更新,不存在时插入的情况。 接下来,我需要回忆MyBatis是否直接支持类似MySQL的ON DUPLICATE KEY UPDATE或者PostgreSQL的ON CONFLICT语句。根据引用3中的示例,MyBatis使用foreach标签处理批量插入,但用户的需求更倾向于单条记录的upsert。这时候可能需要根据不同数据库的特性来编写SQL语句,并在MyBatis的XML映射文件中实现。 用户提供的引用中提到使用BATCH执行器进行批量操作,这可能与当前的upsert需求不太直接相关,但可以作为一个性能优化的点,比如在批量处理时使用BATCH模式提升效率。不过用户当前的焦点是单条记录的插入或更新,所以可能需要先解决基础用法,再提到批量处理时的优化。 然后,我需要考虑不同数据库的实现差异。比如,MySQL使用ON DUPLICATE KEY UPDATE,而Oracle可能使用MERGE INTO语句。因此,在回答时需要分别给出不同数据库的示例,并指出需要根据数据库类型调整SQL语句。 另外,用户可能希望看到如何在MyBatis的XML文件中编写对应的insert语句,以及如何在Java代码中调用。根据引用2中的insert标签示例,可以展示如何将动态SQL数据库特定的语法结合起来。例如,在MySQL中使用ON DUPLICATE KEY UPDATE,在PostgreSQL中使用ON CONFLICT子句。 还需要注意,用户可能需要处理唯一约束冲突的情况,因此要确保示例中包含如何指定唯一键或冲突条件。比如,在MySQL中,需要定义唯一索引或主键,这样ON DUPLICATE KEY UPDATE才能生效。 此外,用户可能关心如何在MyBatis中传递参数,并确保字段映射正确。例如,在XML中使用#{property}来引用Java对象的属性,并指定jdbcType以防止类型错误,如引用4中的示例所示。 最后,需要提醒用户关于不同数据库的兼容性问题,以及在实际使用中需要考虑事务管理和性能优化,如使用BATCH执行器(如引用1所示)来提升批量操作的效率。可能还需要提到在批量upsert时的实现方式,结合foreach标签和数据库特定的语法,但用户当前的问题是单个记录的upsert,所以这部分可以作为扩展内容。 总结来说,回答需要分步骤说明不同数据库的实现方式,提供对应的XML和Java代码示例,并提到注意事项和优化建议,同时结合用户提供的引用内容中的相关信息,确保回答准确且实用。</think>### MyBatis实现`insertOrUpdate`的三种典型方法 #### 方法一:MySQL特有语法(ON DUPLICATE KEY UPDATE) 通过数据库唯一约束触发更新逻辑,适合MySQL数据库: ```xml <insert id="insertOrUpdateUser" parameterType="User"> INSERT INTO users (username, email, create_time) VALUES (#{username}, #{email}, NOW()) ON DUPLICATE KEY UPDATE email = VALUES(email), update_time = NOW() </insert> ``` **实现要点**: 1. 表必须设置唯一约束(如`username`字段的唯一索引) 2. `VALUES(email)`会自动引用INSERT时的参数值 3. 支持批量操作时结合`<foreach>`标签扩展[^3] #### 方法二:PostgreSQL语法(ON CONFLICT) 适配PostgreSQL的冲突处理机制: ```xml <insert id="upsertData"> INSERT INTO sensor_data (device_id, metric_value) VALUES (#{deviceId}, #{value}) ON CONFLICT (device_id) DO UPDATE SET metric_value = EXCLUDED.metric_value, modified = NOW() </insert> ``` #### 方法三:Oracle MERGE语句 兼容Oracle数据库的标准写法: ```xml <update id="mergeEmployee"> MERGE INTO employees t USING (SELECT #{empId} AS emp_id FROM dual) s ON (t.emp_id = s.emp_id) WHEN MATCHED THEN UPDATE SET t.salary = #{salary}, t.update_dt = SYSDATE WHEN NOT MATCHED THEN INSERT (emp_id, salary, create_dt) VALUES (#{empId}, #{salary}, SYSDATE) </update> ``` #### Java调用示例 ```java // 单条记录操作 User user = new User("alice", "alice@example.com"); sqlSession.insert("insertOrUpdateUser", user); // 批量操作(结合BATCH执行器) try (SqlSession batchSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) { UserMapper mapper = batchSession.getMapper(UserMapper.class); userList.forEach(mapper::insertOrUpdateUser); batchSession.commit(); // 显式提交批量操作[^1] } ``` #### 关键注意事项 1. **事务控制**:批量操作建议显式管理事务提交 2. **性能优化**:10,000+数据量时优先选择数据库原生批量语法[^4] 3. **锁机制**:MERGE语句可能产生行锁,需评估并发影响 4. **字段映射**:建议使用`<sql>`标签复用字段列表[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值