0

目标:确保所有代码路径都抛出或返回有效连接;我试图不惜一切代价明确避免连接对象返回为“null”。

这是我能想到的最好的:

public class JdbcConnectionManager {
  public static class JdbcConnectionFailureException extends Exception {
    private static final String JDBC_CONNECTION_INVALID_MESSAGE =
        "JDBC connection invalid, checked with timeout value of: "
            + JdbcConnectionManager.JDBC_CONNECTION_VALIDATION_TIMEOUT_IN_SECONDS;
    private static final long serialVersionUID = 1L;
    public JdbcConnectionFailureException(String message) {
      super(message);
    }
    public JdbcConnectionFailureException(Throwable throwable) {
      super(throwable);
    }
  }
  private static int JDBC_CONNECTION_VALIDATION_TIMEOUT_IN_SECONDS = 3;
  public static Connection getJdbcConnection(
      JdbcConnectionParameters jdbcConnectionParameters)
      throws JdbcConnectionFailureException {
    try {
      if (jdbcConnectionParameters
          .driverNeedsHelpRegisteringUsingClassForName()) {
        Class.forName(jdbcConnectionParameters
            .getClassForNameDriverRegistrationString());
      }
      Connection jdbcConnection =
          DriverManager.getConnection(jdbcConnectionParameters
              .getJbdcConnectionUrl());
      if (!jdbcConnection
          .isValid(JdbcConnectionManager.JDBC_CONNECTION_VALIDATION_TIMEOUT_IN_SECONDS)) {
        throw new JdbcConnectionManager.JdbcConnectionFailureException(
            JdbcConnectionManager.JdbcConnectionFailureException.JDBC_CONNECTION_INVALID_MESSAGE);
      }
      // TODO: perform further validation on the connection
      return jdbcConnection;
    } catch (ClassNotFoundException classNotFoundException) {
      throw new JdbcConnectionManager.JdbcConnectionFailureException(
          classNotFoundException);
    } catch (SQLException sqlException) {
      throw new JdbcConnectionManager.JdbcConnectionFailureException(
          sqlException);
    }
  }
}

我在这里坚如磐石吗?有没有更好、更简洁/优雅/健壮的方式来确保“连接”永远不会“空”?

编辑:

我添加了一个 jdbcConnection.isValid() 检查,但我忽略了输入验证。我会在实际代码中这样做。

4

3 回答 3

1

对我来说看上去很好。

你可以做几件事来改进你的代码。

首先,您应该始终将先决条件放在首位。在您的情况下,首先检查方法输入,例如jdbcConnectionParameters

Exception其次,由于所有捕获的异常都会重新抛出,因此您可以通过使用自定义异常捕获和重新抛出来捕获所有异常。

就像是:

try {
      if (jdbcConnectionParameters.driverNeedsHelpRegisteringUsingClassForName()) {
        Class.forName(jdbcConnectionParameters.getClassForNameDriverRegistrationString());
      }
      jdbcConnection = DriverManager.getConnection(jdbcConnectionParameters.getJbdcConnectionUrl());
} catch (Exception exception) {
      exception.printStackTrace();
      throw new JdbcConnectionManager.JdbcConnectionFailureException(exception);
}
于 2012-06-09T17:05:12.400 回答
1

从 try 块内部返回连接会更清楚:

public static Connection getJdbcConnection(
              JdbcConnectionParameters jdbcConnectionParameters)
                                     throws JdbcConnectionFailureException {
    try {
        if (jdbcConnectionParameters.driverNeedsHelpRegisteringUsingClassForName()) {
            Class.forName(jdbcConnectionParameters
                                .getClassForNameDriverRegistrationString());
        }
        return DriverManager.getConnection(jdbcConnectionParameters
                   .getJbdcConnectionUrl());
        // TODO: perform further validation on the connection
    } 
    catch (ClassNotFoundException classNotFoundException) {
        throw new JdbcConnectionManager.JdbcConnectionFailureException(
            classNotFoundException);
    } 
    catch (SQLException sqlException) {
        throw new JdbcConnectionManager.JdbcConnectionFailureException(
            sqlException);
    }
}

编辑:回答你关于死代码的问题:

jdbcConnection 在这个地方不能为空,因为如果它为空,就会在该行抛出 NPE

if (!jdbcConnection.isValid(...))
于 2012-06-09T17:05:27.337 回答
1

你的代码很好,但对我来说你有点过于复杂了:

public static Connection getJdbcConnection(
  JdbcConnectionParameters jdbcConnectionParameters)
  throws JdbcConnectionFailureException {
    try {
      if (jdbcConnectionParameters.driverNeedsHelpRegisteringUsingClassForName()) {
        Class.forName(jdbcConnectionParameters
            .getClassForNameDriverRegistrationString());
      }
      return DriverManager.getConnection(jdbcConnectionParameters.getJbdcConnectionUrl());
    } catch (ClassNotFoundException classNotFoundException) {
      throw new JdbcConnectionManager.JdbcConnectionFailureException(classNotFoundException);
    } catch (SQLException sqlException) {
      throw new JdbcConnectionManager.JdbcConnectionFailureException(sqlException);
    }
}

还可以考虑使用DataSourceand JdbcTemplatefrom 。如果您将该异常作为原因传递并重新抛出,也不要这样做printStackTrace()- 它将被记录两次。

于 2012-06-09T17:05:29.980 回答