何时创建/初始化准备好的语句

问题描述:

我有以下2种方法的查询类,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(); 
    } 
} 

我转换查询1类至低于其中由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的初学者,并没有遇到类似的代码示例。)

任何建议将不胜感激。

+2

的重新编译“你的背后”可能取决于您的方法被调用的频率,但我建议坚持前者,以便您定期保证资源被清理。在后者(静态)方法中,您无法清理资源。这两种情况都无法处理连接更新,但这是使用前者的另一个原因,所以您可以更好地处理其他数据库问题。 – user1676075 2014-08-27 16:48:43

+1

从这本书http://oreilly.com/catalog/jorajdbc/chapter/ch19.html我认为PreparedStatement,如果你不重复使用它的许多语句,实际上是比常规语句慢一点。当然,PreparedStatement是避免SQL注入的好方法。 – Leo 2014-08-27 17:00:25

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

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

还要注意,即使是ps的可能,因为这可能会影响如何查询必须/应该执行的变化(除了指标,在统计的改变,权限等的变化)