0

Is there anything wrong with using a parent function to handle all the messy catch/finally stuff in a connection pool?

public Connection getConnection() {
    try {
        return this.dataSource.getConnection();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

public ResultSet executeQuery(Connection connection, PreparedStatement stmt) {
    try {
        return stmt.executeQuery();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    return null;
}
4

3 回答 3

3

没有问题,除了你正在吃异常而不是抛出它们。抛出异常是一个更好的主意,允许调用方法采取适当的行动。

注意:如果您可以迁移到 Java 7 并使用资源尝试,那么您将节省大量此类混乱。在此处了解更多信息:http: //docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

于 2013-08-10T01:26:06.450 回答
2

这是Facade Pattern的一个例子。

它没有任何问题,除了你应该使用这些方法static,所以它们是(无状态的)实用方法。

于 2013-08-10T01:25:49.400 回答
0

如果您使用try-with-resources模式并专注于最小化资源的范围,您将拥有更简洁的代码。特别是,您有问题地打开资源(连接和语句)与关闭行为分开。通过拆分它,您很容易犯错误或创建低效的代码。例如,也许您不应该在执行查询后关闭连接。

相反,您通常应该在同一个地方打开和关闭资源,并且在您传递这些资源的任何地方您信任(创建一个不变量)它们是并且将保持打开状态。这清楚地将获取资源行为与使用资源行为区分开来,并让您清楚地限制这些资源的开放范围。

比较您的代码:

Connection conn = getConnection();
PreparedStatement ps = ...; // construct PreparedStatement
ResultSet rs = executeQuery(conn, ps);
// use ResultSet

/* now secretly your Connection and PreparedStatement are closed (even if you wanted
   to use them again) though your result set is still open and needs to be closed.

   Admittedly it's concise, but what's actually going on is very unclear. */

到我的代码:

public static void main(String[] args) {
    try(Connection conn = this.dataSource.getConnection()) {
        // All calls in this block, and only calls in this block, can use the connection
        buildObjectWithDBData(conn); // method does exactly what the name implies
        // do more calls against our connection as needed
    }
}

public static void buildObjectWithDBData(Connection conn) {
    try(PreparedStatement ps = /* generate prepared statement */;
        ResultSet rs = ps.executeQuery()) {
        // do work with result set, populate the data we need
    }
    // at this point we know the connection is alive in a clean, stable state,
    // the resources opened here are closed, and we've done the work we need
}

我承认,我的有点冗长。但它在做什么要清楚得多,在这个过程的每一步,我们都明确地将我们的对象和资源的范围限制在尽可能小的范围内,而不是依赖于任意方法调用的副作用来秘密关闭对象并离开它们仍在范围内,但无法使用。

于 2013-08-10T01:57:52.333 回答