【发布时间】:2011-11-08 23:56:55
【问题描述】:
可能重复:
when to close Connection, Statement, PreparedStatement and ResultSet in JDBC
我已经为 JDBC 连接编写了一个简单的包装器,它可以工作,但我想尽可能地使用最佳实践来改进它。它基本上有open()、close()、isOpened()、select()、insert()、update()、delete()和batch()等方法。为简单起见,我将仅在此处发布前 4 种方法。
public class Query{
private Connection con;
private PreparedStatement ps;
private ResultSet rs;
//Database.open() returns a Connection ready to use
public void open (Database database) throws DatabaseException, SQLException{
if (!isOpened ()){
con = database.open ();
}
}
public void close () throws SQLException{
if (isOpened ()){
if (ps != null) ps.close ();
con.close ();
con = null;
}
}
public boolean isOpened (){
return con != null;
}
//The query string is the query without the word "select" and can use placeholders (?)
//The args param it's just an array owith the values of this placeholders
public ResultSet select (String query, Object[] args) throws SQLException{
if (ps != null) ps.close ();
if (isOpened ()){
ps = con.prepareStatement ("select " + query);
if (args != null){
for (int i=0; i<args.length; i++){
ps.setObject (i+1, args[i]);
}
}
rs = ps.executeQuery ();
}
return rs;
}
}
注意事项:
- 可以重复使用相同的查询对象,例如打开和关闭 它,并在再次打开后。
- 我没有关闭每个查询的连接,我只是关闭 准备好的声明(这是正确的,或者我可以离开准备好的 语句打开是因为 Connection 对象将关闭它?)
- 当我关闭
Connection,所有PreparedStatements 和 他们的ResultSets 也关门了,对吧?
用法:
Database database;
//Database initialization
Query query = new Query ();
query.open (database);
ResultSet rs = query.select ("* from user where name=?", new String[]{ "MyName" });
doSomethingWithResult1 (rs);
//Connection is not closed here
ResultSet rs = query.select ("coordx from point where coordy=? and coordz=?", new Float[]{ 0.1, 0.2 });
doSomethingWithResult2 (rs);
query.close ();
query.open (database);
ResultSet rs = query.select ("* from user where name=?", new String[]{ "MyName" });
doSomethingWithResult1 (rs);
//Connection is not closed here
ResultSet rs = query.select ("coordx from point where coordy=? and coordz=?", new Float[]{ 0.1, 0.2 });
doSomethingWithResult2 (rs);
query.close ();
你怎么看?每次查询后我应该关闭并打开连接吗?我可以在同一连接上的每个查询后打开 PreparedStatement 吗?设计不错?
【问题讨论】:
-
关闭和重新打开每个查询的连接是个坏主意。建立联系真的非常非常昂贵。
-
那么我可以让 PreparedStatement 保持打开状态,还是应该为每个查询关闭它?
-
您可以让一切保持打开状态,直到您真正完成使用数据库。关闭连接将跟踪并关闭它产生的所有内容(语句、结果集)。
-
您可能只使用 Jakarta Commons DBUtils。它似乎和你的包装器做同样的事情。