【问题标题】:When to create/initialize the prepared statement何时创建/初始化准备好的语句
【发布时间】:2014-10-21 08:39:04
【问题描述】:

我有以下带有 2 个方法的 Query 类,insert() 方法经常使用,deleteRecord() 不是。

public class Query1 {

private final static String INSERT = "insert into info values (?, current_timestamp)";
private final static String DELETE_RECORD = "delete from info where stamp = ?";

private static final Connection con = DatabaseConnection.getInstance();

//This method is used frequently
public static void insert(List<String> numList) throws SQLException {
    try (PreparedStatement st_insert = con.prepareStatement(INSERT)) {
        for (int i = 0; i < numList.size(); i++) {
            st_insert.setString(1, numList.get(i));
            st_insert.addBatch();
        }
        st_insert.executeBatch();
    }
}

// This method is NOT used frequently
public static void deleteRecord(Timestamp stamp) throws SQLException {
    try (PreparedStatement st = con.prepareStatement(DELETE_RECORD)) {
        st.setTimestamp(1, stamp);
        st.execute();
    }
}

我将 Query1 类转换为下面的类,其中 insert() 方法使用的 PreparedStatement 在静态块中初始化,因为它经常使用。

public class Query2 {
private final static String INSERT = "insert into info values (?, current_timestamp)";
private final static String DELETE_RECORD = "delete from info where stamp = ?";

private static final Connection con = DatabaseConnection.getInstance();

// Frequently used statements
private static PreparedStatement st_insert;
static {
    try {
        st_insert = con.prepareStatement(INSERT);
    } catch (SQLException ex) {            
    }
}

//This method is used frequently
public static void insert(List<String> numList) throws SQLException {        
    for (int i = 0; i < numList.size(); i++) {
        st_insert.setString(1, numList.get(i));            
        st_insert.addBatch();
    }
    st_insert.executeBatch();
}

// This method is NOT used frequently
public static void deleteRecord(Timestamp stamp) throws SQLException {
    try (PreparedStatement st = con.prepareStatement(DELETE_RECORD)) {
        st.setTimestamp(1, stamp);
        st.execute();
    }
}

考虑到使用准备好的语句,这是否优化了代码,或者这不是一个好习惯?如果没有怎么办? (我是 JDBC 的初学者,还没有遇到过这样的代码示例。)

任何建议将不胜感激。

【问题讨论】:

  • 可能取决于您的方法被调用的频率,但我建议坚持使用前者,以便您定期保证资源被清理。在后一种(静态)方法中,您永远无法清理资源。两种情况都不能处理连接更新,但这将是使用前者的另一个原因,因此您可以更好地处理其他数据库问题。
  • 来自这本书oreilly.com/catalog/jorajdbc/chapter/ch19.html 我认为PreparedStatement,如果你不为许多语句重用它,实际上比普通语句慢一点。当然,PreparedStatement 是避免 SQL 注入的好方法。

标签: java jdbc javadb


【解决方案1】:

你的推理是正确的。频繁执行的查询可以从使用 PreparedStatement 中受益。确切的权衡将因数据库而异。您使用 javadb 进行标记,如果这是您使用的 PreparedStatements 将永远不会变慢,因为常规语句会经历相同的编译过程。

也就是说,我同意那些建议不要在静态块中准备语句的人的观点。 我通常会尝试在构造函数或 init 方法中准备语句,以便可以在经常调用的方法中重用 ps。

还要注意,即使是 ps 也可以“在你背后”重新编译,因为可能会影响查询必须/应该如何执行(添加索引、更改统计信息、更改权限等)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    • 2012-08-11
    相关资源
    最近更新 更多