mysql中on duplicate key update用法(批量操作数据、存在更新,不存在则新增),附mybatis配置

本文介绍如何使用MySQL的ON DUPLICATE KEY UPDATE特性实现数据存在时更新,不存在时插入的操作,尤其适用于批量数据处理,提高数据库操作效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、应用场景

日常开发中,对于一个数据想做到存在即更新,不存在则新增,通常的做法是先查询数据库中是否存在对应的数据,如果存在就使用更新的方法,不存在就使用新增的方法
如果是单个数据,倒也没什么问题,但如果是批量数据的话,会消耗大量的资源来进行查询操作,这样就得不偿失了。
这种情况我们可以使用mysql提供的 on duplicate key update 来进行操作。

2、表结构和示例数据

在这里插入图片描述
在这里插入图片描述

3、使用ON DUPLICATE KEY UPDATE更新单条数据,如下表示需要更新name、gender、birthday、address这些字段。
#用法1:使用values来获取值(推荐,因为插入多个的时候可以用)
INSERT INTO `user` ( id, name, gender, birthday, address )
VALUES( 1, '张三', 1, '2021-02-14', '黑龙江' ) 
ON DUPLICATE KEY UPDATE 
name =VALUES(name),
gender =VALUES(gender),
birthday =VALUES(birthday),
address =VALUES(address)

#用法2:直接使用值
INSERT INTO `user` ( id, name, gender, birthday, address )
VALUES( 1, '张三', 1, '2021-02-14', '黑龙江' ) 
ON DUPLICATE KEY UPDATE 
name = '张三',
gender = 1,
birthday = '2021-02-14',
address = '黑龙江'

mybatis中的用法(自己建立对应的实体类User,一一对应相应的字段)

<insert id="insertUser" parameterType="com.test.User">
    INSERT INTO user(
    id,
    name,
    gender,
    birthday,
    address)
    VALUES
    (#{id},
    #{name},
    #{gender},
    #{birthday},
    #{address})
    ON DUPLICATE KEY UPDATE
    id = VALUES(id),
    name = VALUES(name),
    gender = VALUES(gender)
    birthday = VALUES(birthday),
    address = VALUES(address)
</insert>
4、mybatis 中批量插入数据(list中存放user对象数据)
<insert id="insertUser" parameterType="java.util.List">
    INSERT INTO user(
    id,
    name,
    gender,
    birthday,
    address)
    VALUES
    <foreach collection="list" item="item" index="index" separator=",">
        (#{item.id},
        #{item.name},
        #{item.gender},
        #{item.birthday},
        #{item.address})
    </foreach>
    ON DUPLICATE KEY UPDATE
    id = VALUES(id),
    name = VALUES(name),
    gender = VALUES(gender)
    birthday = VALUES(birthday),
    address = VALUES(address)
</insert>
<think>好的,我现在需要帮助用户解决如何使用MyBatis实现批量插入或更新操作,特别是涉及on duplicate key的情况。用户明确提到了想要一个示例,所以我需要提供一个具体的例子,并结合他们提供的引用内容。 首先,我应该回忆一下MyBatis的相关知识,尤其是批量操作ON DUPLICATE KEY UPDATE用法。根据引用[1],ON DUPLICATE KEY UPDATE在遇到唯一索引冲突时会更新旧行。引用[3]中有一个MyBatis-plus的示例,展示了如何通过XML配置实现批量插入或更新,使用foreach标签生成多个值,并在冲突时更新各字段。这可能是一个好的参考。 接下来,我需要考虑用户是否使用MyBatis还是MyBatis-Plus,因为引用[3]和[4]提到了MyBatis-plus的批量处理,而用户的问题是关于MyBatis的。过,MyBatis本身也可以实现类似的功能,只是配置方式可能有所同。需要确保示例适用于原生MyBatis。 然后,用户可能需要XML配置和对应的Java代码示例。在引用[3]的示例中,使用了insert标签,里面包含了foreach来循环插入值,并在最后加上ON DUPLICATE KEY UPDATE子句。这应该可以直接用于MyBatis,只需调整可能的语法差异。 另外,引用[2]提到PostgreSQL的批量优化参数,但用户的问题可能更关注MySQL,因为ON DUPLICATE KEY UPDATEMySQL的特性。过,可以提一下数据库的差异,但主要示例应该基于MySQL。 还需要注意,用户可能需要了解如何配置useGeneratedKeys和keyProperty,以便获取自动生成的主键,如引用[4]中提到的。这在批量操作中可能很重要,尤其是当插入新记录时需要获取生成的ID。 另外,要确保示例中的表结构和唯一索引正确,比如用户提供的例子中的hh_chain_customer_info表,假设id是主键或者有其他唯一索引。在ON DUPLICATE KEY UPDATE部分,需要更新所有需要变更的字段,使用values()函数来引用插入的值。 可能还需要解释一下XML中的各个部分,比如foreach的作用,separator的设置,以及on duplicate key update后面的字段如何对应。同时,需要提醒用户确保数据库支持该语法,比如MySQL,而其他数据库如PostgreSQL可能有同的语法(如ON CONFLICT ... DO UPDATE)。 最后,生成相关问题,帮助用户进一步了解性能优化、数据库的处理方式以及框架的差异,如MyBatisMyBatis-Plus在批量操作上的同实现方法。</think>以下是使用MyBatis实现批量插入或更新操作的完整实现方案: ### 一、MyBatis批量插入或更新实现 #### 1. XML映射文件配置 ```xml <insert id="batchInsertOrUpdate" parameterType="java.util.List"> INSERT INTO your_table (unique_column, field1, field2, update_time) VALUES <foreach collection="list" item="item" separator=","> (#{item.uniqueValue}, #{item.field1}, #{item.field2}, NOW()) </foreach> ON DUPLICATE KEY UPDATE field1 = VALUES(field1), field2 = VALUES(field2), update_time = NOW() </insert> ``` #### 2. Java接口定义 ```java @Mapper public interface YourMapper { void batchInsertOrUpdate(@Param("list") List<YourEntity> entities); } ``` #### 3. 执行原理 - 当`unique_column`触发唯一索引冲突时,自动执行UPDATE操作 - `VALUES()`函数获取当前INSERT语句中的列值[^1] - 建议更新`update_time`字段记录操作时间 ### 二、关键配置说明 1. **唯一索引要求**: - 表中必须存在`UNIQUE`索引(单列或复合索引) - 示例使用`unique_column`作为唯一性判断依据 2. **批量优化**: - 单次批量建议控制在500-1000条数据 - 可配合`rewriteBatchedStatements=true`连接参数提升性能(MySQL)[^2] 3. **返回值处理**: - 使用`useGeneratedKeys="true"`可获取自增主键 - 批量操作时返回受影响行数=插入数 + 更新数*2 ### 三、MyBatisMyBatis-plus对比 | 特性 | MyBatis原生实现 | MyBatis-plus增强[^3] | |--------------------|------------------------|--------------------------| | SQL控制 | 需手动编写完整SQL | 支持条件构造器自动生成 | | 批量操作 | 需自定义foreach实现 | 内置`saveOrUpdateBatch`方法 | | 主键回写 | 需配置useGeneratedKeys | 自动处理实体类主键回写 | ### 四、性能优化建议 1. **事务控制**: ```java @Transactional(rollbackFor = Exception.class) public void batchProcess(List<YourEntity> data) { yourMapper.batchInsertOrUpdate(data); } ``` 2. **连接池配置**: ```properties # 建议配置连接池参数 spring.datasource.hikari.maximum-pool-size=20 spring.datasource.hikari.minimum-idle=5 ``` 3. **索引优化**: - 确保`ON DUPLICATE KEY`使用的索引具有高选择性 - 避免在频繁更新字段上建立索引
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值