我正在开发一个 Java Spring 服务,该服务从 Oracle 数据库读取 BLOB 类型的字段。这个 BLOB 字段包含一个 zip 文件,我的服务应该在响应正文中将此文件返回给客户端。
我已经实现了以下代码:
public void datasetDownload(String id, HttpServletResponse response) throws SQLException, IOException {
try (Connection connection = dataSource.getConnection()) {
String sql = "SELECT CONTENT FROM MY_TABLE_NAME WHERE ID = ?";
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
preparedStatement.setString(1, id);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
Blob blob = resultSet.getBlob("CONTENT");
try (InputStream inputStream = blob.getBinaryStream();
OutputStream outputStream = response.getOutputStream()) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
deleteRecord(id, connection);
}
}
}
}
}
但是,当我调用此服务时,遇到以下异常:
java.lang.OutOfMemoryError:Java 堆空间
我怀疑该问题是由将 Oracle 数据库中的整个 blob 读取到内存中引起的。为了解决这个问题,我想我需要以较小的块读取 blob 以避免耗尽 Java 堆空间,但我不知道该怎么做。
谢谢您的帮助!
错误发生在哪一行?使用 resultSet.getBinaryStream() 您可以保存一些行,并且它应该使用更少的内存,因为它不会首先加载 blob。