在Java中进行数据库异常处理的更好方法

时间:2012-09-19 09:49:27

标签: java database jdbc

哪一个会更好:针对那种情况的ErrorCode或Exception?

我一直在看这两种错误处理技巧。我不知道每种技术的缺点和优点。

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);
    }
}

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;
    }
}

对于第二种方法,错误代码检索表单配置文件。我们可以根据Error Code添加SQL Vender Code

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

方法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(...);
        }
    }

方法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(...);
        }
    }

5 个答案:

答案 0 :(得分:6)

我建议使用Spring JDBCTemplate。它将翻译大多数现有数据库'未经检查的例外情况的例外情况,例如DataIntegrityViolationException。它还将在消息中包含原始SQL错误。

答案 1 :(得分:2)

奇怪的问题,因为两种方法都做同样的事情:它们在一个似乎未经检查的不同异常中转换一个已检查的SqlException。所以第一个是更好的一个,因为它将它移动到一个方法中。

两者都有待提出一些问题:

  • 是否有一些基础设施可以进行此转换(另一个答案中提到了Spring Template)

  • 你真的想要检查例外,在我看来,他们几乎不值得这么麻烦。

  • 谁正在对异常进行真正的处理,它是否获得了所需的所有信息?我会特别期待一些关于MyException内部失败的事务的其他信息,例如:我们尝试做什么? (例如,更新商务对象);什么样的对象? (例如一个人);我们/用户如何识别对象(例如person.id + person.lastname + person.firstname)。如果您想要生成日志/错误消息,告诉您或您的用户超过“糟糕,有问题”,您将需要此类信息

  • 为什么MyException是可变的(至少在第二个例子中)

答案 2 :(得分:1)

比任何一种设计都更好的设计是通过扩展RuntimeException来取消选中自定义例外。

我希望你的异常包装第一个,所以用这种方式编码也会更好:

MyException exception = new MyException(e); // wrap it.

如果你这样做,第二个是首选。更多信息更好。

答案 3 :(得分:1)

恕我直言,这取决于您的代码与SQL的紧密程度。

如果方法是总是(* 1)与SQL结合,我只会声明并重新抛出SQLException(在清理/关闭资源之后)。然后,具有SQL感知能力的上层方法会根据需要处理它(可能它们需要所有细节,也许它们不需要)。

如果将来某个时候你可以改变另一个不使用SQL的方法,那么我会选择第二个选项。

(1):对这个假设更加悲观:“我认为我们不会改变”应该被解释为“可能我们会想要改变”。 “我们不会改变”意味着“我们不能在不破坏其他任何方法的情况下改变”。

答案 4 :(得分:0)

您将catch异常的方式有所不同。在第一种情况下,您只能catch异常并且您知道错误是什么。在第二种情况下,您必须catch异常并检查代码以查看错误是什么。

相关问题