考虑以下 MySQL 测试表:
CREATE TABLE `customers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
现有样本数据如下:
id name email
-- -------------- ----------------
1 Loblaw, Bob bob@example.com
2 Thompson, Gord gord@example.com
使用默认连接设置compensateOnDuplicateKeyUpdateCounts=false(描述here)以下Java代码
PreparedStatement ps = dbConnection.prepareStatement(
"INSERT INTO customers (name, email) " +
"VALUES (?, ?) " +
"ON DUPLICATE KEY UPDATE " +
"name = VALUES(name), " +
"id = LAST_INSERT_ID(id)");
ps.setString(1, "McMack, Mike");
ps.setString(2, "mike@example.com");
int euReturnValue = ps.executeUpdate();
System.out.printf("executeUpdate returned %d%n", euReturnValue);
Statement s = dbConnection.createStatement();
ResultSet rs = s.executeQuery("SELECT LAST_INSERT_ID() AS n");
rs.next();
int affectedId = rs.getInt(1);
if (euReturnValue == 1) {
System.out.printf(" => A new row was inserted: id=%d%n", affectedId);
}
else {
System.out.printf(" => An existing row was updated: id=%d%n", affectedId);
}
产生以下控制台输出
executeUpdate returned 1
=> A new row was inserted: id=3
现在使用参数值再次运行相同的代码
ps.setString(1, "Loblaw, Robert");
ps.setString(2, "bob@example.com");
控制台输出是
executeUpdate returned 2
=> An existing row was updated: id=1
这表明如果唯一索引导致现有行被更新,.executeUpdate 确实可以返回 2。如果您在实际测试代码方面需要进一步帮助,那么您应该编辑您的问题以包含它。
编辑
进一步测试表明.executeUpdate 将返回 1 如果
- 尝试的 INSERT 被中止,因为它会导致重复的 UNIQUE 键值,和
- 指定的 ON DUPLICATE KEY UPDATE 更改实际上并未修改现有行中的任何值。
这可以通过使用完全相同的参数值连续两次运行上述测试代码来确认。请注意,UPDATE ... id = LAST_INSERT_ID(id)“技巧”确实确保返回正确的 id 值。
如果插入的唯一值是唯一键值,这可能解释了 OP 的测试结果。