在MyBatis中处理大量数据

Alv*_*vin 11 java large-data mybatis

我的目标实际上是将数据库的所有数据转储到XML文件中.数据库不是很大,大约300MB.问题是我的内存限制只有256MB(在JVM中).所以显然我不能把所有内容都读到内存中.

我设法使用iBatis解决了这个问题(是的,我的意思是iBatis,而不是myBatis)通过getList(... int skip, int max)多次调用它来增加skip.这确实解决了我的记忆问题,但我并没有对速度印象深刻.变量名称表明该方法的作用是读取整个结果集跳过然后指定的记录.这听起来对我来说是多余的(我不是说这是方法正在做什么,我只是猜测基于变量名称).

现在,我切换到myBatis 3以获取我的应用程序的下一个版本.我的问题是:有没有更好的方法来处理myBatis中的大块数据块?反正是为了让myBatis处理前N个记录,将它们返回给调用者,同时保持结果集连接打开,这样下次用户调用getList(...)时它将开始从N + 1记录中读取而不做任何记录"退出"?

小智 16

myBatis CAN流结果.您需要的是自定义结果处理程序.通过这种方式,您可以单独获取每一行并将其写入XML文件.总体方案如下:

session.select(
    "mappedStatementThatFindsYourObjects",
    parametersForStatement,
    resultHandler);
Run Code Online (Sandbox Code Playgroud)

其中resultHandler是实现ResultHandler接口的类的实例.这个界面只有一个方法handleResult.此方法为您提供ResultContext对象.从此上下文中,您可以检索当前正在读取的行并使用它执行某些操作.

handleResult(ResultContext context) {
  Object result = context.getResultObject();
  doSomething(result);
}
Run Code Online (Sandbox Code Playgroud)

  • 您的答案缺乏重要细节:您需要在语句中添加@Options(fetchSize = Integer.MIN_VALUE)(或等效的XML).并且它在MyBatis 3.0.5中无效(我使用Eclipse Memory Analyzer进行了检查).我升级到MyBatis 3.1.1,现在流媒体正常工作. (8认同)

And*_*ndy 7

不,MyBatis的不具有完全有能力流结果还没有.

编辑1: 如果您不需要嵌套的结果映射,那么您可以实现自定义结果处理程序来传输结果.在当前发布的MyBatis版本上.(3.1.1)当前限制是指您需要进行复杂的结果映射.NestedResultSetHandler不允许自定义结果处理程序.有一个修复程序,它看起来像3.2目前的目标.见问题577.

总之,要使用MyBatis流式传输大型结果集,您需要.

  1. 实现自己的ResultSetHandler.
  2. 增加提取大小.(如Guillaume Perrot所述)
  3. 对于嵌套结果映射,请使用问题577中讨论的修复程序.此修复程序还解决了大型结果集的一些内存问题.