Java上的MySQL“INSERT ... ON DUPLICATE KEY UPDATE”:如何区分插入/更新/无变化状态

Posted

技术标签:

【中文标题】Java上的MySQL“INSERT ... ON DUPLICATE KEY UPDATE”:如何区分插入/更新/无变化状态【英文标题】:MySQL "INSERT ... ON DUPLICATE KEY UPDATE" on Java: How to Differ Inserted/Updated/NoChange states 【发布时间】:2015-03-03 20:02:21 【问题描述】:

我对 mysql 的 INSERT ... ON DUPLICATE KEY UPDATE 语句的返回值感到困惑。当我在 MySQL 客户端(mysql 终端、phpmyadmin 或 MySQL Workbench)上尝试时,执行结果为以下之一:

1:如果插入了新记录(即没有重复键)。 2:如果存在重复键的情况下更新现有记录。 0:如果执行了更新但没有更改列值。

这些结果是有道理的。但是,当我在 Java 中执行相同的查询(使用 mysql-connector 5.1.34)时,JDBC 的 executeUpdate 方法在插入且没有更改的情况下返回 1,和 2 以防更新成功。更新无效时不返回0。

这是 MySQL JDBC 驱动的错误吗?如果是这样,是否有没有此错误的版本?如果这不是错误,我怎样才能得到与 MySQL 客户端返回的结果相同的结果?

【问题讨论】:

【参考方案1】:

看来您需要在驱动程序属性中手动设置useAffectedRows

经过一番谷歌搜索后,我得到了解决方案。你可以参考这个 MySql Bug 这个INSERT ON DUPLICATE KEY UPDATE return 0 if no change in JDBC ExecuteUpdate

在讨论中还说他们在 5.1.7 中发布了它

编辑你的第二个问题:

useAffectedRows

在连接到服务器时不要设置 CLIENT_FOUND_ROWS 标志(不符合 JDBC,会破坏大多数依赖于 DML 语句的“找到”行与“受影响行”的应用程序),但确实会导致“正确”更新从服务器返回的“INSERT ... ON DUPLICATE KEY UPDATE”语句中计数。

默认值:假

自版本:5.1.7

参考useAffectedRows in JDBC Connector-j

【讨论】:

感谢您的回复。有用。但是,我有几个问题。一、你知道为什么useAffectedRows配置默认为false吗?它有任何缺点、错误或性能问题吗?是否可以将其设置为连接或语句,而不是进行驱动程序范围内的更改? @ovunccetin:: 为您编辑的答案。看来我们不能为了连接而改变它。

以上是关于Java上的MySQL“INSERT ... ON DUPLICATE KEY UPDATE”:如何区分插入/更新/无变化状态的主要内容,如果未能解决你的问题,请参考以下文章

MySQL INSERT ON DUPLICATE KEY UPDATE

mysql insert on duplicate key

MySQL中的`REPLACE`和`INSERT ... ON DUPLICATE KEY UPDATE`之间有啥实际区别?

mysql INSERT ... ON DUPLICATE KEY UPDATE语句

mysql INSERT ... ON DUPLICATE KEY UPDATE语句

Mysql死锁如何排查:insert on duplicate死锁一次排查分析过程