在mybatis 3.4.0版本中新增了一个功能,查询可以返回Cusror类型的数据,类似于JDBC里的ResultSet类,当查询百万级的数据的时候,使用游标可以节省内存的消耗,不需要一次性取出所有数据,可以进行逐条处理或逐条取出部分批量处理。
在使用方式上没有太大变化
mybatis单独使用
XML mapping :
select id,name,salary,skill from employees order by id
Java code :
Cursor employees = sqlSession.selectCursor("getEmployeeNestedCursor");
// Get an iterator on employees
Iterator iter = employees.iterator();
List smallChunk = new ArrayList(10);
while (iter.hasNext()) {
// Fetch next 10 employees
for(int i = 0; i<10 && iter.hasNext(); i++) {
smallChunk.add(iter.next());
}
doSomethingWithAlreadyFetchedEmployees(smallChunk);
smallChunk.clear();
}
在3.4.0版本中,不支持@select注解,在3.4.1版本中已经修复:
@select("select id,name,salary,skill from employees order by id")
public Cursor getEmployeeNestedCursor();
==Cursor在session关闭的同时被关闭==
spring 整合mybatis的使用
在mybatis-spring的整合中,mybatis中sqlSession中由org.mybatis.spring.SqlSessionTemplate实现替代。sqlSession关闭是由SqlSessionTemplate管理,所以返回后的Cursor对象是已经被关闭了的,无法使用。
在mybatis-spring 1.3.0版本中新增加了MyBatisCursorItemReader类,需要spring-batch jar包的支持,通过MyBatisCursorItemReader我们可以对Cursor进行操作。
bean.xml
queryId:使用Cursor的查询sql id。
try{
Map paramsMap = new HashMap<>();
//查询的sql所3需要的参数
paramsMap.put("oredCriteria",transferExample.getOredCriteria());
paramsMap.put("orderByClause",transferExample.getOrderByClause());
//设置参数
myMyBatisCursorItemReader.setParameterValues(paramsMap);
//打开
myMyBatisCursorItemReader.open(new ExecutionContext());
List smallChunk = new ArrayList(10);
Employee employee;
while ((employee=myMyBatisCursorItemReader.read())!=null) {
// Fetch next 10 employees
for(int i = 0; i<10 && iter.hasNext(); i++) {
smallChunk.add(iter.next());
}
doSomethingWithAlreadyFetchedEmployees(smallChunk);
smallChunk.clear();
}catch(Exception e){
//do some
}finally{
myMyBatisCursorItemReader.close();
}
}