问题描述
public List<Employee> getEmployeeDataByDate(Date dateCreated) throws Exception {
List<Employee> listDetails = new ArrayList<>();
sqlServTemplate.query(SyncQueryConstants.RETRIEVE_EMPLOYEE_RECORDS_BY_DATE,new Object[] { dateCreated },new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws sqlException {
Employee emp = new Employee();
emp.setEmployeeID(rs.getString("employeeID"));
emp.setFirstName(rs.getString("firstName"));
emp.setLastName(rs.getString("lastName"));
emp.setMiddleName(rs.getString("middleName"));
emp.setNickName(rs.getString("nickName"));
byte[] res = rs.getBytes("employeeImage");
Blob blob = new SerialBlob(res);
emp.setEmployeeImage(blob);
// .....
listDetails.add(emp);
}
});
return listDetails;
}
这里我正尝试检索employee表的记录。由于BLOB数据的原因,是说 OutOfMemoryError:Java堆空间。有人可以帮我吗?
这是一个独立的应用程序,我正在从一个表同步到另一个表。因此无法使用分页。每天2k记录将在午夜由cron作业同步。给我一些想法,我该如何解决这个问题。
SELECT * FROM Employees with(nolock) WHERE cast (datediff (day,dateCreated) as datetime) >= ?
此查询根据日期为我提供了所有数据(每天约2k条记录)。 如果我要发表评论
byte[] res = rs.getBytes("employeeImage");
Blob blob = new SerialBlob(res);
emp.setEmployeeImage(blob);
此行则没有问题。否则,它会引发错误。
请提供一些想法,如果可能,请提供一些示例代码。 我从这个工作的第二天开始苦苦挣扎。
解决方法
正如其他一些评论者所提到的,您可以增加堆空间或限制从查询中返回的记录数量,并分批处理它们。
,您正在读取MB大小的图像(以字节为单位),它将占用您的HEAP内存。 而是尝试使用BinaryStream:
InputStream image = rs.getBinaryStream("employeeImage");
,
您可以将每个用户一次处理,而不是将每个用户添加到列表中。将每条记录从源数据库中拉出时,将其放在另一个数据库中,而不是将它们添加到导致OOM错误的列表中。如果下游还有其他处理,则将一个类注入此DAO中,以处理对目标DB的实际处理/写入。