A Generic JDBC Abstraction Framework(3)--Converting JDBC Exceptions to Generic Exceptions

Converting JDBC Exceptions to Generic Exceptions

转换jdbc异常到通用异常

In the class diagram above, all the classes above the horizontal line are generic. These are the exceptions that calling code will work with.

在上面的类图中,所有的在水平线上的类是通用的。这些异常将和调用代码一起工作。

The exceptions below the line areJDBC-specific subclasses of generic data access exceptions. Most callers won't use these exceptions directly (because such use would tie them to JDBC), but they provide more specific information if necessary. The BadSqlGrammarException, for example, extends the generic InvalidDataAccessResourceUsageException, and is thrown when the specified SQL is invalid.

在水平线下的异常是jdbc通用数据访问异常。大部分的调用者将不会直接的用这些异常(因为这些用法将关联到jdbc),但是如果必要的话他们提供了更详细的信息。BadSqlGrammarException,例如,继承了通用InvalidDataAccessResourceUsageException,被抛出当特定sql是不可用的。

So far we haven't considered how to convert between SQL exceptions and our generic exceptions. To do this we'll need to examine SQLState or vendor codes. However, as SQLState codes aren't sufficient to diagnose all problems, we must retain the option of RDBMS-specific implementation.

到目前为止我们还没有考虑如何在sql exception和我们的通用异常之间转换。为了做这个,我们需要检查sqlstate或者厂商代码。然而,sqlstate没有足够的暴露所有的问题,我们必须保持特定的rdbms实现的选择。

We do this by creating an interface that defines the translation functionality required, enabling us to use any implementation without affecting the working of our abstraction framework. (As usual, interface-based design is the best way to achieve portability). Our JDBC abstraction layer will use an implementation of the com.interface21.jdbc.core.SQLExceptionTranslater interface, which knows how to translate SQLExceptions encountered during JDBC operations to exceptions in our generic hierarchy:

我们靠创建了一个接口来做这个,这个接口定义了要求的转换功能,使我们去用任何实现不需要影响抽象框架的工作。(通常,基于接口的设计是最好的方式去获得可移植性)。我们的jdbc抽象层将用一个com.interface21.jdbc.core.SQLExceptionTranslater 接口的实现,知道如何去转换SQLExceptions 的发生在jdbc操作异常在我们的通用层次中。

public interface SQLExceptionTranslater {
DataAccessException translate (String task,
String sql,
SQLException sqlex);
}

The default implementation is com.interface21.jdbc.core.SQLStateSQLExceptionTranslater, which uses the portable SQLState code. This implementation avoids the need for chains of if/else statements by building a static data structure of SQLState class codes. The following is a partial listing:

默认的实现是,用可移植的sqlstate代码。实现避免了if/else语句的链的需要靠构建了一个sqlstate的静态数据结构类代码,下面的是局部列表:


com.interface21.jdbc.core.SQLStateSQLExceptionTranslater, public class SQLStateSQLExceptionTranslater
implements SQLExceptionTranslater {

private static Set BAD_SQL_CODES = new HashSet();

private static Set INTEGRITY_VIOLATION_CODES = new HashSet();

static {
BAD_SQL_CODES.add("42");
BAD_SQL_CODES.add("65");

INTEGRITY_VIOLATION_CODES.add("23");
INTEGRITY_VIOLATION_CODES.add("27");
INTEGRITY_VIOLATION_CODES.add("44");
}

public DataAccessException translate (String task, String sql,
SQLException sqlex) {

String sqlstate = sqlex.getSQLState();
if (sqlstate != null) {
String classCode = sqlstate.substring(0, 2);
if (BAD_SQL_CODES. contains(classCode))
throw new BadSqlGrammarException("(" + task +
"): SQL grammatical error "' + sql + ""', sql, sqlex);
if (INTEGRITY_VIOLATION_CODES. contains (classCode))
throw new DataIntegrityViolationException("(" + task +
"): data integrity violated by SQL "' + sql + ""', sqlex);
}

// We couldn't categorize the problem
return new UncategorizedSQLException("(" + task +
"): encountered SQLException [" + sqlex.getMessage() +
"]", sql, sqlex);
}
}

The following partial listing illustrates an Oracle-specific implementation, com.interface21.jdbc.core.oracle.OracleSQLExceptionTranslater, which uses the vendor code to identify the same range of problems. Note that vendor codes are far more expressive than SQLState codes:

下面的一部分的列表基于特定与oracle的实现,com.interface21.jdbc.core.oracle.OracleSQLExceptionTranslater,用了厂商代码去区分相同范围的问题。注意厂商代码比sqlstate代码更明确。

public class OracleSQLExceptionTranslater
implements SQLExceptionTranslater {

public DataAccessException translate(String task, String sql,
SQLException sqlex) {

switch (sqlex.getErrorCode()) {
case 1 :
// Unique constraint violated
return new DataIntegrityViolationException(
task + ": " + sqlex.getMessage(), sqlex);

case 1400:
// Can't insert null into non-nullable column
return new DataIntegrityViolationException(
task + ": " + sqlex.getMessage(), sqlex);

case 936 :
// Missing expression
return new BadSqlGrammarException(task, sql, sqlex);

case 942 :
// Table or view does not exist
return new BadSqlGrammarException(task, sql, sqlex);
}

// We couldn't identify the problem more precisely
return new UncategorizedSQLException(" ( " + task +
"): encountered SQLException [" +
sqlex.getMessage() + "]", sql, sqlex);
}
}

ps:吐个槽,为啥总是which,it,that子句,不会翻译丫丫丫…

posted @ 2012-12-08 22:26  sqtds  阅读(342)  评论(0编辑  收藏  举报