编辑:我想我需要代码来代替我说话......插入方法之前的数据库检查唯一性?
一个关于我的问题的简单例子。
在数据库中创建用户,电子邮件和用户名是唯一的。如果唯一性检查没有通过,我需要确切地知道哪个字段/列/是否导致错误。
我想要实现
void createUser(String email, String username, String password)
throws EmailExistingException, UsernameExistingException
{
//TODO: Create the user or throw exception according to error.
}
不错的办法
void createUser(String email, String username, String password)
throws EmailExistingException, UsernameExistingException
{
//Do some query first.
if (emailExists(email)) throw EmailExistingException;
if (usernameExists(username)) throw UsernameExistingException;
//TODO: Create the user.
}
什么是错的 - 典型的检查插入之前,永远都不会被接受。
没那么糟办法
//During database creation
db.users.setUnique("email", true);
db.users.setUnique("username", true);
void createUser(String email, String username, String password)
throws UserCreationException
{
try {
//TODO: Create the user.
} catch (SomeSortOfDatabaseException e) {
throw UserCreationException("some message", e);
}
}
什么不是那么好 - 它很可能我只是得到错误代码和串消息例外。但我需要让用户知道重复的字段,以便他们可以相应地进行修改,这是我无法通过此代码实现的。也许一些数据库驱动程序的错误可以给你非常具体的细节,但我认为依靠驱动程序不是一个好方法,因为如果你想在将来改变数据库,它会杀了你。
我的做法
//During database creation
db.users.setUnique("email", true);
db.users.setUnique("username", true);
void createUser(String email, String username, String password)
throws EmailExistingException, UsernameExistingException
{
try {
//TODO: Create the user.
} catch (SomeSortOfDatabaseException e) {
if (emailExists(email)) throw EmailExistingException;
if (usernameExists(username)) throw UsernameExistingException;
throw ServerException("some message", e);
}
}
它实际上是越来越好,但我不喜欢我目前的做法,很多(在现实世界中许多这些独特的领域是可以改变的,你知道我在说什么)。所以我只是好奇在实际生产中对于这个问题常见的方法是什么。任何意见将不胜感激。
哪个数据库?有些数据库本身支持这一点。 – Bohemian
'一些数据库本地支持这个。'绝对是我提到的问题,并不是那么糟糕的做法。无论如何,我很想听听哪些数据库支持这个以及如何完成,当然还有线程安全。 – toyknight
例如,mysql具有'update ... on duplicate key ...'。 – Bohemian