在mybatis 3.4.0版本中新增了一个功能,查询可以返回Cusror<T>类型的数据,类似于JDBC里的ResultSet类,当查询百万级的数据的时候,使用游标可以节省内存的消耗,不需要一次性取出所有数据,可以进行逐条处理或逐条取出部分批量处理。
在使用方式上没有太大变化
mybatis单独使用
XML mapping :
<select id="getEmployeeNestedCursor" resultMap="results" resultOrdered="true">
select id,name,salary,skill from employees order by id
</select>
Java code :
Cursor<Employee> employees = sqlSession.selectCursor("getEmployeeNestedCursor");
// Get an iterator on employees
Iterator<Employee> iter = employees.iterator();
List<Employee> 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<Employee> 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
<bean id="myMyBatisCursorItemReader" class="org.mybatis.spring.batch.MyBatisCursorItemReader">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
<property name="queryId" value=""/>
</bean>
- queryId:使用Cursor的查询sql id。
try{
Map<String,Object> paramsMap = new HashMap<>();
//查询的sql所3需要的参数
paramsMap.put("oredCriteria",transferExample.getOredCriteria());
paramsMap.put("orderByClause",transferExample.getOrderByClause());
//设置参数
myMyBatisCursorItemReader.setParameterValues(paramsMap);
//打开
myMyBatisCursorItemReader.open(new ExecutionContext());
List<Employee> 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();
}
}
网友评论