在JDBC/iBatis 3中迭代大型结果集的最佳方法是什么?

问题描述:

我们试图迭代数据库中的大量行并将其转换为对象。行为如下:在JDBC/iBatis 3中迭代大型结果集的最佳方法是什么?

  • 结果将按序列号排序,当序列号发生变化时将创建一个新对象。创建的对象将被发送到外部服务,有时必须等待,然后再发送另一个数据(这意味着下一组数据将不会立即使用)
  • 我们已经在iBatis 3中投入了代码,因此iBatis解决方案将会对我们来说是最好的方法(我们已经尝试过使用RowBounds,但没有看到它如何进行迭代)。
  • 我们想平衡最小化内存使用量和减少数据库行程。
  • 我们也接受纯粹的JDBC方法,但我们希望解决方案能够在不同的数据库上工作。

更新1

  • 我们需要尽量少调用DB越好(1次调用将是理想的情况下),同时还防止使用过多内存的应用程序。这种类型的问题有没有其他解决方案可能是纯JDBC或任何其他技术?

UPDATE 2

  • 查询将后端驱动并且将只有1个实例在给定时间执行。

感谢并希望听到您对此的见解。

看来你需要某种分页。 iBatis通过查询中的标准LIMIT/OFFSET参数(以及iBatis 3中的RowBounds)执行此操作。

但似乎(如果我正确的话)您还使用iBatis的GROUP BY功能,以便选择返回带有N1 distint“idx”字段的N个记录,从而创建N1“父”对象每个人有几个子对象(总共创建了N个子对象)。或类似的东西。

不幸的是(可以理解)do not mix well

我没有在这里看到任何银弹,人们可以想到很多方法,每种方法都有其缺点 - 很难评估没有更多的信息。

如果主要对象是“大”(许多记录),并且每一个都将被单独处理(通过远程服务器访问),你甚至可能想要做一个临时分页,每页有一个对象,内部记住previosuly读取ID(类似SELECT ... FROM ... WHERE id = (SELECT MIN(id) FROM .... WHERE id > #lastid#))

+0

1.我有一种感觉,iBatis使用LIMIT/OFFSET,我想这意味着它需要为每个页面打对数据库? 2.我们在Java端进行分组,因此不需要在查询中使用group by关键字,我们只需要将结果按id排序,这样我们就可以在处理之前完成使用相同id的子项创建一个对象下一个对象。 3.您的adhoc分页听起来像是RowBounds方法的一个很好的选择。这样我们保证只有下一个对象会被检索。我会给你一个尝试和检查性能。 感谢您的帮助leonbloy! – 2010-04-28 01:56:01

+0

我添加了一个新的要求,即尽可能减少DB往返次数。希望您也可以对更新发表评论。谢谢! – 2010-04-28 10:36:50

+1

我坚持要在一个数据库查询中这样做,看看RowHandler或ResultHandler - (或者更加异常地,返回一个ResultSet/Cursor - 或者还原为普通的JDBC)。但是,如果为每个“对象”远程完成的动作应该给出响应(快速 - 不依赖于某些人为交互),并且您可以相信循环将完成,那么这是合理的。 – leonbloy 2010-04-28 13:36:16

我们需要尽量少调用DB越好(1次调用将是理想的情况下),同时还防止使用过多内存的应用程序。这种类型的问题有没有其他解决方案可能是纯JDBC或任何其他技术?

你真的不应该担心数据库调用的数量。只需查询最终用户需要一次查看的数据。它不能更有效地完成。谷歌也不会查询整个数据库,只显示前10个数字。不,它正好查询那10个数据以供显示,无一例外。这比将整个数据库拖入/复制到应用程序的内存并对其进行处理要快得多,效率更高。利用RDBMS的力量。这就是它的发明/意图。

+0

谢谢BalusC。对不起,但我忘了提及这不是一个用户驱动的查询,而是一个由后端触发的查询。不知道为什么老板想要一个数据库调用,我提到它可能很难平衡内存使用方式,但他建议继续尝试这是为什么我仍然在寻找其他的选择。 – 2010-04-28 13:26:49

+0

+1 BalusC是对的,一般来说(我怀疑特别也是) – leonbloy 2010-04-28 13:30:08

+1

@保罗:好吧,如果老板说的话......:/和他说话。说服他更多。 – BalusC 2010-04-28 13:46:27