Mybatis 3.4.0 Cursor的使用

在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();
    }
}

推荐阅读更多精彩内容

  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 2,348评论 0 3
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 84,267评论 14 122
  • 百战程序员_ Java1573题 QQ群:561832648489034603 掌握80%年薪20万掌握50%年薪...
    Albert陈凯阅读 11,842评论 2 32
  • 官方文档 简介 入门 XML配置 XML映射文件 动态SQL Java API SQL语句构建器 日志 一、 JD...
    拾壹北阅读 2,363评论 0 52
  • 【一直以来我其实没什么女生朋友,所以我很珍惜出现在我身边的每一个人。只要她真心实意对我好,我便会掏心掏肺的对她好。...
    巫马静女阅读 37评论 0 0