众所周知,在java开发中,涉及到数据库操作时,总会需要一系列的连接数据库的操作类的实例化和使用,如Connection类,PreparedStatement类/Statement类还有ResultSet类。但是,每每使用时,我们总需要在try/catch语句中,finally块中关闭所有资源。否则,如若不关,则会轻易耗尽系统CPU资源。
前几天在练习一个小系统时,突然发现。如下代码。
//查询表
public ResultSet queryExecute(String sql)
{
try {
ct = this.getConnection();
ps = ct.prepareStatement(sql);
rs = ps.executeQuery();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}finally
{
this.close();
}
return rs;
}
如若在正常情况下查询完并没有什么问题,但是在使用model2模式开发时,为了分离数据操作层和业务逻辑层。我们有时候需要操作该函数所返回的ResultSet返回值时就大问题了,如若直接使用“rs”,则会抛出异常:
java.sql.SQLException: Operation not allowed after ResultSet closed(结果集已关闭,无法操作。)
这个时候,内心就郁闷了,如若不关闭资源那又会耗CPU,关闭了则无法操作结果集。感觉碰到一个矛盾体了。几番整治中,才发现了CachedRowSetImpl这个类。
于是,上述代码则改为:
//查询表
public CachedRowSetImpl queryExecute(String sql)
{
try {
ct = this.getConnection();
ps = ct.prepareStatement(sql);
rs = ps.executeQuery();
//填充离线结果集
rowSet = new CachedRowSetImpl();
rowSet.populate(rs);
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}finally
{
this.close();
}
return rowSet;
}
将ResultSet类的实例传给CachedRowSetImpl类的实例,然后返回CachedRowSetImpl的实例。接受该返回值的变量直接可以为ResultSet类的实例,毫无影响。Good job!