You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java操作MariaDB:如何获取Upsert操作对应的ID?

问题描述

表结构

users (id, name, email, age)
id is autoincrement
name varchar and unique
email varchar
age decimal

使用的SQL语句

INSERT INTO users (name, email, age)
VALUES ('Alice', 'alice@example.com', 30)
ON DUPLICATE KEY UPDATE
    name = VALUES(name),
    age = VALUES(age);

Java获取ID的代码

ResultSet rs = stmt.getGeneratedKeys();
int generatedKey = 0;
if (rs.next()) {
    generatedKey = rs.getInt(1);
}

插入操作时能正常获取generatedKey,但执行更新操作时,由于ID已存在无法获取生成的键。请问有没有办法获取该插入/更新操作对应的ID?


解决方案

有两种实用的方法可以解决这个问题:

方案一:修改SQL语句,利用MySQL的145971函数

修改后的SQL语句如下:

INSERT INTO users (name, email, age)
VALUES ('Alice', 'alice@example.com', 30)
ON DUPLICATE KEY UPDATE
    name = VALUES(name),
    age = VALUES(age),
    id = LAST_INSERT_ID(id);

原理:MySQL的145971函数如果传入参数,会将该参数值设置为函数的返回值。更新操作时把已存在的id传入该函数,这样执行完语句后,调用getGeneratedKeys()就能拿到对应的id,和插入操作的逻辑完全一致,不需要修改原有的Java代码。

方案二:通过影响行数判断操作类型,更新时主动查询ID

可以通过executeUpdate()的返回值区分是插入还是更新操作,再针对性处理:

int updateCount = stmt.executeUpdate();
int targetId = 0;
if (updateCount == 1) {
    // 插入操作,直接获取生成的ID
    ResultSet rs = stmt.getGeneratedKeys();
    if (rs.next()) {
        targetId = rs.getInt(1);
    }
    rs.close();
} else if (updateCount == 2) {
    // 更新操作,利用name的唯一性查询ID
    String querySql = "SELECT id FROM users WHERE name = ?";
    PreparedStatement queryStmt = conn.prepareStatement(querySql);
    queryStmt.setString(1, "Alice");
    ResultSet rs = queryStmt.executeQuery();
    if (rs.next()) {
        targetId = rs.getInt(1);
    }
    rs.close();
    queryStmt.close();
}

原理:在MySQL中,ON DUPLICATE KEY UPDATE执行插入时返回1,执行更新(且有行被修改)时返回2。根据这个返回值判断操作类型,更新时通过唯一约束的name字段查询对应的id。


内容的提问来源于stack exchange,提问作者orochi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 03:33:19