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 更高层次的抽象并且它确实尊重所有映射。