使用MyBatis ResultHandler
可以一次处理一个结果对象。
不幸的是,如果ResultMap
很复杂,则对象将是不完整的。
有解决方法吗?
我需要提取约50万行,并且我希望按单个对象进行处理和丢弃。
答案 0 :(得分:1)
您可以尝试使用ResultHandler
的{{3}}来代替Iterable
,并且可以这样使用(在有序排列结果的情况下,请参见上文Cursor
API Java doc以获取详细信息):
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
更高级的抽象,并且确实尊重所有映射。
答案 1 :(得分:0)
一半的内存行可能浪费内存,尤其是当您同时运行多个并发进程/用户时。您可能会耗尽服务器堆。
您没有发布正在使用的数据库,但是由于获取大小有效,因此我认为它类似于Oracle,DB2或PostgreSQL。
现在,即使您设法分批检索行(一次说1000条),也需要了解一些查询无法逐步运行,并且数据库服务器在发送给您之前需要读取所有500000行第一个。这意味着,即使您的Web服务器不会承受很多负载,但多个并发查询仍然会在数据库中产生瓶颈。您不会解决问题,而只是将其传输到数据库。不好。
另一方面,您是否考虑过在返回行时使用某种分页?一些查询使您可以非常有效地执行此操作。例如,查询一次可以返回10,000行。但是请不要使用OFFSET
;这对于您的情况而言效率很低。您需要使用Key Set Pagination,假设这些行是按一组唯一列进行排序的。
最后,为什么需要读取这么多行?对于批处理/每晚处理,我会做类似的事情,但对于在线回复则不会。您的用例是什么?