在单个方法中重用连接对象

问题描述 投票:0回答:2

我遇到过这种模式。当您需要执行多个SQL语句时,在单个方法中重用Connection对象是否可以?

我最初的想法是在继续之前关闭所有资源:

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
    conn = ConnectionFactory.getConnection();
    ps = conn.prepareStatement("SELECT * FROM MYTABLE WHERE COL=?");
    ps.setString(1, "val");
    rs = ps.executeQuery();
    // get values used to determine the next statement type
} catch (SQLException e) {
    LOG.error("SQL failed.", e);
} finally {
    if(rs != null){rs.close();}
    if(ps != null){ps.close();}
    if(conn != null){conn.close();}
}
// Then another SQL statement is needed (either an UPDATE or INSERT).
// Repeat the same pattern to open, use and close the connection

做以下事情是否安全?如果它是安全的,是否有真正的好处?

//... boilerplate
try {
    conn = ConnectionFactory.getConnection();
    ps = conn.prepareStatement("SELECT * FROM MYTABLE WHERE COL=?");
    ps.setString(1, "val");
    rs = ps.executeQuery();
    // ... more

    ps = conn.prepareStatement("UPDATE MYTABLE SET COL=?")
    // ... etc
} finally {
    if(rs != null){rs.close();}
    if(ps != null){ps.close();}
    if(conn != null){conn.close();}
}
java jdbc
2个回答
1
投票

你应该做的是使用try-with-resources

//... boilerplate
try (Connection conn = ConnectionFactory.getConnection()) {
    try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM MYTABLE WHERE COL=?")) {
        ps.setString(1, "val");
        try (ResultSet rs = ps.executeQuery()) {
            // ... more
        }
    }

    try (PreparedStatement ps = conn.prepareStatement("UPDATE MYTABLE SET COL=?")) {
        // ... etc
    }
}

1
投票

重用连接不是反模式,它完全没问题。重用连接是两个语句在同一本地JDBC事务中执行的唯一方法。如果您正在编写访问关系数据库的应用程序,则应了解事务。

实现异常处理的方式容易出错,因为如果在关闭任何资源时抛出异常,则以后的资源不会被关闭。如果关闭preparedStatement会抛出异常,则连接不会关闭。 try-with-resources将是一种改进,但是the way try-with-resources handles the edge cases让我避免使用JDBC来支持嵌套的try-finally块。

如果这里有反模式,它直接使用JDBC,它是非常低级的,涉及大量的剪切和粘贴,并且不容易使用事务或连接池。使用Spring可以处理详细信息,例如划分数据库事务,使用连接池以及为您关闭资源。

© www.soinside.com 2019 - 2024. All rights reserved.