過帳(未測試)的代碼段,這應該給你基本思路:
/**
* Implementors of this interface should only convert current row to byte array and return it.
*
* @author yura
*/
public interface RowToByteArrayConverter {
byte[] rowToByteArray(ResultSet resultSet);
}
public class ResultSetAsInputStream extends InputStream {
private final RowToByteArrayConverter converter;
private final PreparedStatement statement;
private final ResultSet resultSet;
private byte[] buffer;
private int position;
public ResultSetAsInputStream(final RowToByteArrayConverter converter, final Connection connection, final String sql, final Object... parameters) throws SQLException {
this.converter = converter;
statement = createStatement(connection, sql, parameters);
resultSet = statement.executeQuery();
}
private static PreparedStatement createStatement(final Connection connection, final String sql, final Object[] parameters) {
// PreparedStatement should be created here from passed connection, sql and parameters
return null;
}
@Override
public int read() throws IOException {
try {
if(buffer == null) {
// first call of read method
if(!resultSet.next()) {
return -1; // no rows - empty input stream
} else {
buffer = converter.rowToByteArray(resultSet);
position = 0;
return buffer[position++] & (0xff);
}
} else {
// not first call of read method
if(position < buffer.length) {
// buffer already has some data in, which hasn't been read yet - returning it
return buffer[position++] & (0xff);
} else {
// all data from buffer was read - checking whether there is next row and re-filling buffer
if(!resultSet.next()) {
return -1; // the buffer was read to the end and there is no rows - end of input stream
} else {
// there is next row - converting it to byte array and re-filling buffer
buffer = converter.rowToByteArray(resultSet);
position = 0;
return buffer[position++] & (0xff);
}
}
}
} catch(final SQLException ex) {
throw new IOException(ex);
}
}
@Override
public void close() throws IOException {
try {
statement.close();
} catch(final SQLException ex) {
throw new IOException(ex);
}
}
}
這是非常直觀的實現,它可以在以下幾個方面進行改進:
- 代碼如果和else在讀取方法之間的重複可被移除 - 它被張貼只是爲了澄清
- 而不是重新創建用於每行的字節數組緩衝液(
new byte[]
是昂貴的歌劇更復雜的邏輯可以實現使用字節數組緩衝區,該緩衝區僅被初始化一次,然後被重新填充。然後每個人都應該改變RowToByteArrayConverter.rowToByteArray
方法的簽名int fillByteArrayFromRow(ResultSet rs, byte[] array)
應返回填充的字節數,並填寫傳遞字節數組。
因爲字節數組包含符號字節它可以包含-1
(實際上255
作爲無符號字節是),並因此表明流的不正確結束,所以& (0xff)
用於符號字節轉換成無符號字節整數值。有關詳細信息,請參閱How does Java convert int into byte?。
也請注意,如果網絡傳輸速度較慢,這可能會保持打開的結果集 很長一段時間,因而存在數據庫問題。
希望這有助於...
你看過使用jdbc緩存行集嗎?這可能對你想要做的事情有幫助。 http://docs.oracle.com/javase/1.5.0/docs/api/javax/sql/rowset/CachedRowSet.html – ChadNC
不,但那會怎樣幫助我?問題不在於斷開連接,而是在內存中導致結果。 –
這就是緩存的行集。提供了一種更簡單的方法,通過網絡將查詢結果發送到其他設備,應用程序等。 – ChadNC