问题
I couldn't able to find how to achieve lazy loading(even in MyBatis docs).
My mapper xml is shown below:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.FooMyBatisLazyFetch">
<select id="callFooProc"
parameterType="com.example.FooProcBundle"
statementType="CALLABLE">
{call FooProc(
#{arg1, jdbcType=VARCHAR, mode=IN},
#{arg2, jdbcType=VARCHAR, mode=IN},
#{arg3, jdbcType=VARCHAR, mode=IN},
#{error, jdbcType=NUMERIC, mode=OUT},
#{res2, jdbcType=CURSOR, mode=OUT, resultMap=FooProcResult}
)
}
</select>
<resultMap id="FooProcResult" type="com.example.FooProcResult">
<result property="bar1" column="barcol1"/>
<result property="bar2" column="barcol2"/>
<result property="bar3" column="barcol3"/>
<result property="bar4" column="barcol4"/>
<result property="bar5" column="barcol5"/>
</resultMap>
</mapper>
Pojo Class:
public class FooProcResult {
private String bar1;
private String bar2;
private String bar3;
private String bar4;
private String bar5;
}
public class FooProcBoondle {
private String arg1;
private String arg2;
private String arg3;
private Integer error;
private List<FooProcResult> res2;
//getters,setters, etc
}
And usage code;
FooProcBundle bundle = new FooProcBundle();
bundle.setArg1("foo");
bundle.setArg2("bar");
bundle.setArg3("baz");
fooMyBatisLazyFetch.callFooProc(bundle);
Integer error = bundle.getError();
if(error == 123) /*some condition*/ {
List<FooProcResult> res2 = bundle.getRes2();
// iterate res2
--->// Only here CURSOR may be opened and executed
}
i.e. I don't want to fetch res2 unless my code explicitly request for it. That particular cursor is quite heavy, and I don't want to execute it when it's not required(but mybatis does it).
Also I want to apply this to generator-like procedures (Oracle call them "Pipelined Table Functions" they yield result, sleep and wait until caller fetches next row - wakeup and calculate next. Usually they called this way: SELECT * FROM TABLE(GenProc(arg1,arg2))
.
Any ideas about the configuration required to achieve this?
回答1:
Procedure output cursor parameters are processed in class org.apache.ibatis.executor.resultset.DefaultResultSetHandler in method handleOutputParameters and then in method handleRefCursorOutputParameter. You will note that the code in its current state, does not allow to do want you seek, the only "custom option" used is the resultMap that must be provided. I also would have appreciated some more options just like lazy loading, custom result handler, and some logs to be able to monitor the actual execution time and the fetch time.
This could be achieved in JDBC and would require configuration that is not implemented in the framework.
来源:https://stackoverflow.com/questions/37386083/lazy-fetching-in-mybatis