在 Java 中处理数据库异常的更好方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12492315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Better way for DB exception handling in java
提问by Zaw Than oo
Which one will be better: ErrorCode or Exception for that situation?
哪个会更好:ErrorCode 或 Exception 对于那种情况?
I have ever been seeing these two error handling techniques. I don't know the disadvantages and advantages for each technique.
我曾经见过这两种错误处理技术。我不知道每种技术的优缺点。
public void doOperation(Data data) throws MyException {
try {
// do DB operation
} catch (SQLException e) {
/* It can be ChildRecordFoundException, ParentRecordNotFoundException
* NullValueFoundException, DuplicateException, etc..
*/
throw translateException(e);
}
}
or
或者
public void doOperation(Data data) throws MyException {
try {
// do DB operation
} catch (SQLException e) {
/* It can be "CHILD_RECORD_FOUND, "PARENT_RECORD_NOT_FOUND"
* "NULL_VALUE_FOUND", "DUPLICATE_VALUE_FOUND", etc..
*/
String errorCode = getErrorCode(e);
MyException exc = new MyException();
exc.setErrorCode(errorCode);
throw exc;
}
}
For second method, the error code retrieve form configuration file. We can add Error Code
based on the SQL Vender Code
.
对于第二种方法,错误代码检索表单配置文件。我们可以Error Code
根据SQL Vender Code
.
SQL_ERROR_CODE.properties
SQL_ERROR_CODE.properties
#MySQL Database
1062=DUPLICATE_KEY_FOUND
1216=CHILD_RECORD_FOUND
1217=PARENT_RECORD_NOT_FOUND
1048=NULL_VALUE_FOUND
1205=RECORD_HAS_BEEN_LOCKED
Caller client for method 1
方法 1 的调用方客户端
try {
} catch(MyException e) {
if(e instanceof ChildRecordFoundException) {
showMessage(...);
} else if(e instanceof ParentRecordNotFoundException) {
showMessage(...);
} else if(e instanceof NullValueFoundException) {
showMessage(...);
} else if(e instanceof DuplicateException) {
showMessage(...);
}
}
Caller client for method 2
方法 2 的调用方客户端
try {
} catch(MyException e) {
if(e.getErrorCode().equals("CHILD_RECORD_FOUND")) {
showMessage(...);
} else if(e.getErrorCode().equals("PARENT_RECORD_NOT_FOUND") {
showMessage(...);
} else if(e.getErrorCode().equals("NULL_VALUE_FOUND") {
showMessage(...);
} else if(e.getErrorCode().equals("DUPLICATE_VALUE_FOUND") {
showMessage(...);
}
}
采纳答案by Jens Schauder
Strange question, since both approaches do the same thing: they transform a checked SqlException in a different exception which seems to be unchecked. So the first one is the better one because it moves this into a single method.
奇怪的问题,因为这两种方法都做同样的事情:它们将已检查的 SqlException 转换为似乎未检查的不同异常。所以第一个是更好的,因为它将它移动到一个单一的方法中。
Both leave some questions to be asked:
两人都留下了一些问题要问:
Isn't there some infrastructure that can do this conversion (Spring Template was mentioned in another answer)
Do you really want checked Exceptions, in my mind they are hardly ever worth the trouble.
Who is doing the real handling of the exception, does it get all the information needed? I would normaly expect some additional information about the transaction that failed inside of MyException, like: What did we try to do? (e.g. update a busines object); On what kind of object? (e.g. a Person); How can we/the user Identify the object (e.g. person.id + person.lastname + person.firstname). You will need this kind of information if you want to produce log/error message that tell you or your user more than 'Oops, something is wrong'
Why is MyException mutable (at least in the 2nd example)
是否有一些基础设施可以进行这种转换(另一个答案中提到了 Spring 模板)
你真的想要检查异常吗,在我看来,它们几乎不值得麻烦。
谁在真正处理异常,它是否获得了所有需要的信息?我通常会期望一些关于在 MyException 内部失败的事务的附加信息,例如:我们尝试做什么?(例如更新业务对象);在什么样的物体上?(例如一个人);我们/用户如何识别对象(例如person.id + person.lastname + person.firstname)。如果您想生成的日志/错误消息告诉您或您的用户不仅仅是“哎呀,出了点问题”,您将需要此类信息
为什么 MyException 是可变的(至少在第二个例子中)
回答by artbristol
I recommend using Spring's JDBCTemplate
. It will translate most existing databases' exceptions into unchecked exceptions that are specific, e.g. DataIntegrityViolationException
. It will also include the original SQL error in the message.
我建议使用 Spring 的JDBCTemplate
. 它将大多数现有数据库的异常转换为特定的未经检查的异常,例如DataIntegrityViolationException
。它还将在消息中包含原始 SQL 错误。
回答by duffymo
A better design than either one would be to make your custom exceptions unchecked by extending RuntimeException
.
比任何一种都更好的设计是通过扩展RuntimeException
.
I'd want your exception to wrap the first one, so coding it this way would be better, too:
我希望您的异常包装第一个,因此以这种方式编码也会更好:
MyException exception = new MyException(e); // wrap it.
If you do that, the second one is preferred. More information is better.
如果这样做,则首选第二个。更多信息更好。
回答by SJuan76
IMHO, it depends as how tightly your code is coupled with SQL.
恕我直言,这取决于您的代码与 SQL 结合的紧密程度。
If the method is to always(*1) be coupled with SQL, I would just declare and rethrow the SQLException
(after cleanup / closing resources). Upper methods that are SQL-aware would then process it as they see fit (perhaps they need all the detail, perhaps they not).
如果该方法总是(*1) 与 SQL 结合,我将只声明并重新抛出SQLException
(在清理/关闭资源之后)。然后,SQL 感知的上层方法将按照他们认为合适的方式处理它(也许他们需要所有细节,也许他们不需要)。
If sometime in the future you could change the method for another which does not use SQL, then I would go for the second option.
如果将来某个时候您可以更改另一个不使用 SQL 的方法,那么我会选择第二个选项。
(1): Be extra pessimistic with this assumption: "I think we are not going to change" should be interpreted as "Probably we will want to change". "We are not going to change" means "We cannot change without breaking lots of other methods anyway".
(1):对这个假设更加悲观:“我认为我们不会改变”应该被解释为“可能我们会想要改变”。“我们不会改变”的意思是“无论如何,如果不打破许多其他方法,我们就无法改变”。
回答by basiljames
One differnce would the way you will catch
the exception. In the first cases you can just catch
the exception and you know what the error is. In the second case you have to catch
the exception and check the code to see what the error is.
一个不同之处在于您将catch
例外的方式。在第一种情况下,您可以只catch
处理异常并且您知道错误是什么。在第二种情况下,您必须catch
查看异常并检查代码以查看错误是什么。