我使用 JDBC(mysql 数据库)编写 Java 程序。当我违反 mysql 完整性(我尝试插入相同的主键值)时,我捕获SQL 异常。 我应该以它可能永远不会发生的方式编写它(首先是布尔函数检查主键值是否已经在数据库中,然后调用插入),还是可以通过异常处理它?例子 :
catch (SQLException ex) {ex.printStackTrace(); showSomeErrorDialog(); }
确实基本上有两种方法可以实现这一点:
在同一事务中插入 --inside 之前测试是否存在记录。
根据SQL 规范确定SQLException#getSQLState()
捕获的SQLException
开头23
是否违反约束。它可能是由更多的因素引起的,而不仅仅是“违反”约束。您不应该将每个都修改为违反约束。SQLException
public static boolean isConstraintViolation(SQLException e) {
return e.getSQLState().startsWith("23");
}
我会选择第一个,因为它在语义上更正确。事实上,这并不是一个例外情况。你即知道它可能会发生。但它可能会在事务不同步的重并发环境中失败(不知不觉地或优化性能)。然后,您可能想要确定异常。
也就是说,您通常不应该在主键上违反约束。在使用技术键作为主键的精心设计的数据模型中,它们通常由数据库本身管理。该字段不应该是唯一键吗?
有两个可能的答案:
正如其他人提到的,有两种可能的方法,一种是测试然后插入/更新,否则处理 SQL 异常。这两种方法都有其缺点:
因此,我将提出一种将两者混合的方法。
这可能需要几行额外的代码,但它肯定会提高性能并生成友好的错误消息。