数据访问对象(DAO)中的方法是应该抛出还是捕获它的异常?

时间:2013-03-05 20:17:50

标签: java spring java-ee architecture dao

我在数据访问对象中有一个Java方法。这个非常简单的方法将两个整数值插入数据库。

public void saveHourMin(int hour, int min) throws SQLException{
psInsert.setInt(1, hour);
psInsert.setInt(2, min);
psInsert.executeUpdate();
}

这个方法,或者一般来说,任何DAO方法,在抛出SQLException时抛出异常,还是应该捕获并记录异常,然后通过返回代码通知用户?哪个是使用Spring的应用程序的正确方法?

3 个答案:

答案 0 :(得分:5)

您不能指望调用者始终检查返回代码,最好抛出异常。

如果你抛出SQLException然后那将是混乱的,你可能会得到更高层,或者在每个方法上添加“throws Exception”,或者只是吃异常。这两种选择都不好。

Spring的方式是提供一个异常转换器,它接受原始的SQLException并抛出一个RuntimeException的子类,它包含原始的SQLException作为原因,并尝试尽可能多地提供有关错误的信息,包括使用供应商错误代码,用于决定要抛出的特定子类。 如果您使用Spring的任何jdbcTemplates,那么您将获得异常转换功能,因此您不需要包含任何异常捕获或引入数据访问对象。

如果您不想使用Spring,可以在DAO中捕获SQLException并抛出RuntimeException,包括原始的SQLException作为原因。对于大多数SQLExceptions,您无能为力,只是想快速失败并记录异常。

答案 1 :(得分:1)

我会说不。捕获SQLException,然后抛出一个RuntimeException,如果是后代,则抛出一个。您不希望使用数据访问异常污染您的应用程序。例如,您不应该在GUI层中捕获SQLExceptions。我不会根据返回代码构建应用程序。

通过抛出RuntimeException,您不会强制调用者捕获它。

答案 2 :(得分:1)

我会创建一个名为DAOException的新异常,它不是RuntimeException,并强制该方法的用户处理此类异常,可能是枚举作为描述异常的DAOException的成员(可能添加实际异常)内部作为内部例外)。

因此抛出的异常可能如下所示:

new DAOException(DAOException.TYPE.SQLE, e)

并且saveHourMin方法抛出DAOException。

这样一来,如果你遇到各种各样的问题,它们都处于同样的例外状态,你不需要处理不同的问题。

我建议使用一般异常而不是运行时的原因是因为我不希望它是可选的来处理异常。无论是谁调用这种方法都必须意识到这样的问题可能会发生并提供相关的处理(即使这意味着抛出一个新的RuntimeException,上帝保佑,但现在由他们决定,这是他们的决定)。作为一般的经验法则,我会避免使用RuntimeExceptions,因为它们会使执行路径不清楚(“有人可能会在执行路径的某个地方捕获它,否则会杀死应用程序,因此可以让它继续”不会发出声音对我好。)