gpt4 book ai didi

mysql - 数据库 - 唯一约束违规的处理

转载 作者:行者123 更新时间:2023-11-29 18:25:48 30 4
gpt4 key购买 nike

我有一个用户创建屏幕,其中包含各种用户详细信息以及名字和手机号码。我有一个相应的 USER 表,其中名字和手机号码形成一个复合唯一键。该表还定义了其他完整性约束。

当在“创建用户”屏幕上输入的用户数据违反此限制时,需要向用户显示“用户友好”错误消息。

当发生这种违规时,我从 MySQL 数据库得到的异常是:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1-1' for key `uk_FIRST_NAME__MOBILE_idx`

有两个选项可显示有意义的消息(例如:“错误:给定手机号码的用户名已存在,请更改其中之一”)。

选项 1:在此异常的 catch block 中,解析 MySQL 异常消息并查找“uk_FIRST_NAME__MOBILE_idx”。如果存在,请显示如上所述的用户友好消息。

选项 2:编写一个 DAO 级别 API,将名字和手机号码作为唯一的两个参数,触发数据库查询以查看是否存在与该名字/手机组合匹配的现有记录。如果为 true,则向用户显示错误消息;否则,运行插入查询将记录的用户插入到 USER 表中。

我不喜欢选项 1,因为它需要我“解析”异常消息,这不是一个干净的解决方案。我也不喜欢选项 2,因为它需要我在数据库上运行“两个查询”,这比选项 1 效率低,选项 1 是单个查询解决方案。

问题:还有比这两个更好的其他选择吗?如果不是,以上两种方法中哪一种是正确的?

最佳答案

我认为“选项2”(在尝试插入之前手动检查约束)是可怕的,不仅仅是因为竞争危险(可以使用 locking reads 来避免),而且(正如您所注意到的)因为额外的加载数据库:毕竟,手动检查约束完全否定了在数据库中使用约束的目的和好处。

我同意解析错误消息字符串感觉“肮脏”,但字符串是 well defined 。人们甚至可以引用底层的 errmsg.txt 或源头文件。

一旦从错误消息中提取了 key 名称,就可以使用 KEY_COLUMN_USAGE用于识别有问题列的信息架构:

public static final int ER_DUP_ENTRY = 1062;
public static final int ER_DUP_ENTRY_WITH_KEY_NAME = 1586;

public static final String REGEX_DUP_ENTRY_WITH_KEY_NAME =
"Duplicate entry '(.*)' for key '(.*)'";

// ...


try {
// ...
} catch (MySQLIntegrityConstraintViolationException e) {
switch (e.getErrorCode()) {
case ER_DUP_ENTRY:
case ER_DUP_ENTRY_WITH_KEY_NAME:
Pattern p = Pattern.compile(REGEX_DUP_ENTRY_WITH_KEY_NAME);
Matcher m = p.matcher(e.getMessage());

SQLQuery query = session.createSQLQuery(
" SELECT COLUMN_NAME" +
" FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE" +
" WHERE CONSTRAINT_SCHEMA = :schema" +
" AND CONSTRAINT_NAME = :key"
);
query.setString("schema", "my_schema");
query.setString("key" , m.group(2));

showDuplicateError(query.list());

break;
}
}

关于mysql - 数据库 - 唯一约束违规的处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46209167/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com