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
相关产品推荐
相关产品推荐

