在 MyBatis 中处理大量数据

2022-09-03 18:30:34

我的目标实际上是将数据库的所有数据转储到 XML 文件中。数据库不是很大,大约是300MB。问题是我的内存限制仅为256MB(在JVM中)。所以很明显,我不能把所有东西都读进记忆里。

我设法使用iBatis(是的,我的意思是iBatis,而不是myBatis)通过多次调用它来解决这个问题,并递增。这确实解决了我的记忆问题,但我对速度印象不深。变量名称表明,该方法在后台执行的操作是读取整个结果集跳过,然后执行指定的记录。这对我来说听起来很多余(我不是说这就是方法正在做的事情,我只是根据变量名称猜测)。getList(... int skip, int max)skip

现在,我切换到myBatis 3作为我的应用程序的下一个版本。我的问题是:有没有更好的方法来处理myBatis中的大量数据块?是否无论如何都要使myBatis进程前N条记录,将它们返回给调用方,同时保持结果集连接打开,以便下次用户调用getList(...)时,它将开始从N + 1记录读取而不执行任何“跳过”?


答案 1

myBatis CAN 流结果。您需要的是自定义结果处理程序。这样,您可以单独获取每一行并将其写入 XML 文件。整体方案如下所示:

session.select(
    "mappedStatementThatFindsYourObjects",
    parametersForStatement,
    resultHandler);

其中 resultHandler 是实现 ResultHandler 接口的类的实例。此接口只有一个 方法 。此方法为您提供一个 ResultContext 对象。从此上下文中,您可以检索当前正在读取的行,并对其进行操作。handleResult

handleResult(ResultContext context) {
  Object result = context.getResultObject();
  doSomething(result);
}

答案 2

不可以,mybatis 还没有完全流式传输结果的能力。

编辑1:如果不需要嵌套结果映射,则可以实现自定义结果处理程序来流式传输结果。在当前发布的MyBatis版本上。(3.1.1) 当前的限制是当您需要进行复杂的结果映射时。嵌套结果集处理程序不允许自定义结果处理程序。修复程序可用,看起来当前针对的是 3.2。请参阅问题 577

总之,要使用 MyBatis 流式传输大型结果集,您需要这样做。

  1. 实现您自己的 ResultSetHandler
  2. 增加抓取大小。(如下文所述,纪尧姆·佩罗特)
  3. 对于嵌套结果映射,请使用问题 577 中讨论的修复程序。此修复还解决了大型结果集的一些内存问题。

推荐