在实际的工作中,偶尔需要处理数据的数据量比较大,这个时候就需要考虑在有限的内存下高效处理这些数据。
用Springbatch和MyBatisPagingItemReader处理数据
Mybatis提供了一个实现ItemStreamReader接口的MyBatisPagingItemReader类,用于分页处理大量数据。
使用MyBatisPagingItemReader的时候需要在查询语句中添加limit参数_skikrows和_pagesize,Mapper的查询语句如下:
MyBatisPagingItemReader在初始MyBatisPagingItemReader的时候需要指定pagesize的大小和queryId,下面就是一个实例,分页大小为,并指定查询的数据。
在分页大小是1万时,处理了一百万数据需要10分钟左右,页数越大的时候查询的时间越长。
Java连接Mysql使用Cursor处理数据
在用jdbc连接数据库Mysql处理大量数据的时候,可以考虑流的形式来一行一行处理数据,不用担心发生OOM。
对于Mysql在创建Statement的时候指定几个参数,这几个参数就是通知驱动程序想要一行一行的获取数据。
ResultSet.TYPE_FORWARD_ONLY:游标只能向后
ResultSet.CONCUR_READ_ONLY:并发常量,表示ResultSet指定的对象不能被更新
setFechSize:设置为Integer.MIN_VALUE
创建statement注意:如果使用上面的参数对于一个同一个连接不能执行其他的查询直到读取完上一个数据为止。
如果想一次读取多条数据,可以设置Fetchsize大于1的数值,此时需要设置一个连接属性useCursorFetch=true。
useCursorFetch属性设置使用MyBatisCursorItemReader读取数据
前面说过如果想使用Mysql的Cursor,必须设置几个参数,有两种实现方式,一种为mapper的xml文件中指定,另一种使用Mybatis的
Option注解。1、在Mapper文件中指定resulsetType和fetchSize,注意如果一条一条读取,需要设置fetchSize为Integer.MIN_VALUE,否则设置一个正整数。
Mapper文件2,使用
Option注解:Options(fetchSize=Integer.MIN_VALUE,resultSetType=ResultSetType.FORWARD_ONLY)最后初始化MyBatisCursorItemReader如下:
MyBatisCursorItemReaderMybatis怎么创建Statement
在PreparedStatementHandler类中初始化Statement的时候根据不同的参数来创建。如果ResultSetType的类型不为ResultSetType.DEFAULT获取mappedStatement中的ResultSetType。
初始化Statement创建完Statement之后会设置FetchSize,首先获取mappedStatement中的FetchSize。
设置FetchSize最后
1、Mybatis使用Cursor的时候如果遇到这个问题:
Cause:java.sql.SQLException:Nooperationsallowedafterstatementclosed.
请升级Mybatis版本大于等于3.5.3
2、如果设置Fetchsize后没生效,请设置连接的属性useCursorFetch=true