我使用wildfly-8.2.0.Final。此服务器上有连接池(Oracle)。 请看下面的代码:
public ArrayList<HashMap<String, Object>> fetchSome(String query)
throws OracleQueryProcessorException {
ArrayList<HashMap<String, Object>> result = new ArrayList<HashMap<String, Object>>();
try {
Context initCtx = new InitialContext();
DataSource ds = (DataSource) initCtx.lookup(driver);
try (Connection con = ds.getConnection();
PreparedStatement stmt = con.prepareStatement(query)) {
try (ResultSet rs = stmt.executeQuery()) {
ResultSetMetaData rsmd = rs.getMetaData();
rs.next();
HashMap<String, Object> row = new HashMap<String, Object>();
String name = rsmd.getColumnName(1);
Object value = rs.getObject(1);
if (value instanceof Blob) {
Blob bl = (Blob) value;
if (bl.length() > 0)
value = bl.getBinaryStream();
else
value = null;
}
row.put(name, value);
result.add(row);
}
} catch (SQLException e) {
throw new OracleQueryProcessorException();
}
} catch (NamingException e) {
throw new OracleQueryProcessorException();
}
return result;
}
这是这个功能的用法:
InputStream is = (InputStream) fetchSome("SELECT BLOB_FIELD FROM TEST WHERE ID = 1").get(0).get("BLOB_FIELD");
if (is != null) {
byte[] a = new byte[3];
is.read(a);
}
从这个流中读取是有效的!!它怎么样?连接已关闭(因为使用try-with-resources子句)。从这个流中读取不会从池中获取任何连接(所有池的连接都可用)。
答案 0 :(得分:0)
fetchSome()
打开Connection
,发送查询,然后将数据读回到生成的ArrayList中。然后fetchSome
关闭Connection
并返回ArrayList
。您感兴趣的代码会从返回的ArrayList
中读取,而不是从您正确注意到的Connection
开始关闭。
当您的方法返回时,所有数据库通信都已完成,并且所有数据都已复制到返回的列表中,然后可以根据需要随时读取它,而不需要{{1再次。
答案 1 :(得分:0)
它真的适用于各种BLOB尺寸吗?好的门槛是:
OCI级别的AFAIK(C客户端库)LOB可能是“预先分配”的.i.e。 BLOB的一小部分可以发送给客户端,尽管客户端尚未请求。这应该减少数据库和客户端之间的往返次数。
此外,您应该尝试检查v $ instance视图以检查连接是否确实已关闭。有时JDBC和Oracle之间的合作很棘手。
例如,通过Connection.createBLOB()创建的临时LOB与数据库的任何其他临时lobs不同。我认为这是因为Oracle数据库无法与JVM GC通信,并且它不知道Java实例何时被处理掉了。所以这些lobs“永远”保存在数据库中。