Cam*_*n S 10 java sql-server jtds
我需要一个Java函数,它返回SQL SELECT查询的结果,作为InputStream通过网络发送结果的另一个系统的参数.
但是,InputStream必须String使用自定义分隔符(即通常但不总是CSV).
虽然我可以轻松创建一个函数来检索结果,创建一个分隔符String,最后将其转换String为一个InputStream,但SQL结果通常会太大而无法在内存中处理.此外,在返回结果之前处理整个结果集将导致不必要的等待时间.
如何返回一个InputStream迭代SQL结果并发送从数据库返回的已处理(分隔)数据?
发布(未测试)代码片段,它应该为您提供基本的想法:
/**
* 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是非常直接的实现,可以通过以下方式进行改进:
new byte[]成本高昂的操作),可以实现更复杂的逻辑来使用字节数组缓冲区,该缓冲区仅初始化一次然后重新填充.然后应该更改RowToByteArrayConverter.rowToByteArray方法的签名,int fillByteArrayFromRow(ResultSet rs, byte[] array)该签名应返回填充的字节数并填充传递的字节数组.因为字节数组包含有符号字节,所以它可以包含-1(实际上255是无符号字节)并因此指示不正确的流结束,因此& (0xff)用于将有符号字节转换为无符号字节作为整数值.有关详细信息,请参阅Java如何将int转换为字节?.
还请注意,如果网络传输速度很慢,这可能会长时间保持打开结果集,从而给数据库带来问题.
希望这可以帮助 ...
| 归档时间: |
|
| 查看次数: |
6357 次 |
| 最近记录: |