Java - MyBatis - 一次处理一条记录
Java - MyBatis - process one record at a time
使用 MyBatis ResultHandler
一次可以处理一个结果对象。
不幸的是,如果 ResultMap
很复杂,则对象将不完整。
有解决办法吗?
我需要提取大约 500000 行,我想按单个对象处理和丢弃。
内存中的 50 万行可能会浪费内存,特别是如果您同时有多个并发 processes/users 运行ning。您可能会耗尽服务器堆。
您没有post您使用的是什么数据库,但由于提取大小有效,我假设它是 Oracle、DB2 或 PostgreSQL 之类的数据库。
现在,即使您设法小批量检索行(假设一次 1000 行),您也需要了解某些查询不能 运行 逐渐进行,并且数据库服务器需要读取在向您发送第一行之前,所有 500000 行。这意味着,即使您的 Web 服务器不会承受大量负载,但多个并发查询无论如何都会在数据库中产生瓶颈。您不会解决问题,而只是将其传输到数据库。不太好。
另一方面,您是否考虑过在 return 行时使用某种分页?一些查询允许您非常有效地做到这一点。例如,查询可以一次 return 10,000 行。但请不要使用 OFFSET
;这对你的情况来说效率很低。您将需要使用 Key Set Pagination,假设行按 唯一 列集排序。
最后,为什么要读这么多行?我会为 batch/nightly 流程做这样的事情,但不会为在线回复做这样的事情。你的用例是什么?
你可以尝试使用 Cursor 而不是 ResultHandler
,它是 Iterable
并且可以像这样使用(在结果有序的情况下,见上文 Cursor
API java 文档了解详情):
MyEntityMapper.java
@Select({
"SELECT *",
"FROM my_entity",
"ORDER BY id"
})
Cursor<MyEntity> getEntities();
MapperClient.java
MyEntityMapper mapper = session.getMapper(MyEntityMapper.class);
try (Cursor<MyEntity> entities = mapper.getEntities()) {
for (MyEntity entity:entities) {
// process one entity
}
}
它比 ResultHandler
更高层次的抽象并且它确实尊重所有映射。
使用 MyBatis ResultHandler
一次可以处理一个结果对象。
不幸的是,如果 ResultMap
很复杂,则对象将不完整。
有解决办法吗?
我需要提取大约 500000 行,我想按单个对象处理和丢弃。
内存中的 50 万行可能会浪费内存,特别是如果您同时有多个并发 processes/users 运行ning。您可能会耗尽服务器堆。
您没有post您使用的是什么数据库,但由于提取大小有效,我假设它是 Oracle、DB2 或 PostgreSQL 之类的数据库。
现在,即使您设法小批量检索行(假设一次 1000 行),您也需要了解某些查询不能 运行 逐渐进行,并且数据库服务器需要读取在向您发送第一行之前,所有 500000 行。这意味着,即使您的 Web 服务器不会承受大量负载,但多个并发查询无论如何都会在数据库中产生瓶颈。您不会解决问题,而只是将其传输到数据库。不太好。
另一方面,您是否考虑过在 return 行时使用某种分页?一些查询允许您非常有效地做到这一点。例如,查询可以一次 return 10,000 行。但请不要使用 OFFSET
;这对你的情况来说效率很低。您将需要使用 Key Set Pagination,假设行按 唯一 列集排序。
最后,为什么要读这么多行?我会为 batch/nightly 流程做这样的事情,但不会为在线回复做这样的事情。你的用例是什么?
你可以尝试使用 Cursor 而不是 ResultHandler
,它是 Iterable
并且可以像这样使用(在结果有序的情况下,见上文 Cursor
API java 文档了解详情):
MyEntityMapper.java
@Select({
"SELECT *",
"FROM my_entity",
"ORDER BY id"
})
Cursor<MyEntity> getEntities();
MapperClient.java
MyEntityMapper mapper = session.getMapper(MyEntityMapper.class);
try (Cursor<MyEntity> entities = mapper.getEntities()) {
for (MyEntity entity:entities) {
// process one entity
}
}
它比 ResultHandler
更高层次的抽象并且它确实尊重所有映射。