ポスティング(テストされていない)のコードスニペットは、:
/**
* 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);
}
}
}
これは非常に単純で実装され、それは次の方法で改善することができます。
- コードreadメソッドのifとelseとの間の重複を取り除くことができます - 各行のバイト配列バッファを再作成する代わりに、
- のように投稿されました(
new byte[]
は高価なオペラですより洗練されたロジックを実装して、バイトアレイバッファを使用することができます。バイトアレイバッファは、一度だけ初期化されてから再充填されます。 1つはint fillByteArrayFromRow(ResultSet rs, byte[] array)
にRowToByteArrayConverter.rowToByteArray
メソッドの署名を変更する必要があります。この場合、埋められたバイト数が返され、渡されたバイト配列が埋められます。
バイト配列は、署名されたバイトが含まれているので(実際255
符号なしバイトなどである)-1
を含有し、したがって、そう& (0xff)
を整数値として、符号なしバイトに符号付きバイトを変換するために使用される、ストリームの不正確な終了を示すことができます。詳細はHow does Java convert int into byte?を参照してください。
ネットワークの転送速度が遅い場合、これによりオープン結果が になる可能性があり、データベースに問題が発生する可能性があります。
希望これは、私は次のように導入することで、@Yuraによって提案された答えを改善するだろう...
jdbcキャッシュセットを使用してみましたか?それはあなたがやろうとしていることに役立つかもしれません。 http://docs.oracle.com/javase/1.5.0/docs/api/javax/sql/rowset/CachedRowSet.html – ChadNC
いいえ、どうすればそれが役に立ちますか?問題は、接続を開いたままではなく、結果をメモリに保存していることです。 –
これは、キャッシュされた行セットと同じものです。ネットワーク経由で他のデバイス、アプリケーションなどにクエリの結果を送信する簡単な方法を提供します。 – ChadNC