Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中DB异常处理的更好方法_Java_Database_Jdbc - Fatal编程技术网

java中DB异常处理的更好方法

java中DB异常处理的更好方法,java,database,jdbc,Java,Database,Jdbc,对于这种情况,哪一个更好:错误代码还是例外 我见过这两种错误处理技术。我不知道每种技术的优缺点 public void doOperation(Data data) throws MyException { try { // do DB operation } catch (SQLException e) { /* It can be ChildRecordFoundException, ParentRecordNotFoundException

对于这种情况,哪一个更好:错误代码还是例外

我见过这两种错误处理技术。我不知道每种技术的优缺点

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

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

SQL\u错误\u代码属性

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

比这两种方法都好的设计是通过扩展
RuntimeException
使自定义异常不受检查

我想让您的异常包装第一个异常,因此以这种方式编码也会更好:

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

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

我建议使用Spring的
JDBCTemplate
。它会将大多数现有数据库的异常转换为特定的未检查异常,例如
DataIntegrityViolationException
。它还将在消息中包含原始的SQL错误。

IMHO,这取决于代码与SQL的耦合程度

如果方法是始终(*1)与SQL耦合,我只需声明并重新调用
SQLException
(在清理/关闭资源之后)。然后,支持SQL的上层方法将按照它们认为合适的方式处理它(也许它们需要所有细节,也许它们不需要)

如果将来某个时候您可以将该方法更改为另一个不使用SQL的方法,那么我将选择第二个选项


(1) 当前位置对此假设要格外悲观:“我认为我们不会改变”应解释为“我们可能会想要改变”。“我们不会改变”的意思是“无论如何,我们不能在不破坏许多其他方法的情况下进行改变”。

奇怪的问题,因为这两种方法做的事情是相同的:它们将选中的SqlException转换为另一个似乎未选中的异常。所以第一个是更好的,因为它将其移动到一个方法中

两者都留下了一些问题要问:

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

  • 你真的想要检查异常吗?在我看来,它们几乎不值得麻烦

  • 谁在真正处理异常,它是否获得了所需的所有信息?我通常希望得到一些关于MyException内部失败的事务的附加信息,比如:我们试图做什么?(例如,更新业务对象);什么样的物体?(例如某人);我们/用户如何识别对象(例如person.id+person.lastname+person.firstname)。如果您想生成日志/错误消息,告诉您或您的用户更多信息,而不是“哎呀,有什么不对劲”,则需要此类信息

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


一种不同的方式是捕获异常。在第一种情况下,您可以捕获异常,然后知道错误是什么。在第二种情况下,您必须
捕获
异常并检查代码以查看错误是什么。

为什么
运行时异常
更好?任何使用此代码的开发人员都会在异常发生时(可能是在生产时)发现异常。C#已将习惯用法从未检查异常改为检查异常。Spring框架与您所做的完全一样,只是比12年前要好得多。他们使用未经检查的异常。为什么您认为,第二种方法保留了更多信息?所有信息都来自异常,该异常在第一个示例中作为参数传递。我知道Java中的SQLException是一个已检查异常,它显式保留了供应商SQL错误代码,这是其他已检查异常无法做到的。我假设第二个就是这样。
MyException exception = new MyException(e); // wrap it.