确保* all *代码路径返回有效的JDBC连接或抛出异常(禁止“null”)

时间:2012-06-09 16:57:33

标签: java jdbc nullpointerexception

目标:确保所有代码路径 throw 或返回有效连接;我试图明确地避免不惜一切代价将连接对象返回为" 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);
    }
  }
}

我在这里坚如磐石吗?是否有更好,更简洁/更优雅/更健壮的方式来确保"连接"从来没有" null"?

编辑:

我添加了一个jdbcConnection.isValid()检查但是我遗漏了输入验证。我将在实际代码中执行此操作。

3 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分: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在这个地方不能为null,因为如果它为null,那么NPE就会被抛出

if (!jdbcConnection.isValid(...))

答案 2 :(得分: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);
    }
}

另请考虑使用中的DataSourceJdbcTemplate。如果您将该异常作为原因并重新抛出,也不要printStackTrace() - 它将被记录两次。