mybatis如何对大量数据的游标查询
作者:喵主子
这篇文章主要介绍了mybatis如何对大量数据的游标查询问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
mybatis对大量数据的游标查询
mapper定义
@Mapper public interface NewsRepository { String simpleQuery="select news.id,news.title,news.keywords," + " news.url,news.author," + " data.content,news.inputtime,news.updatetime " + " from news news join news_data data on news.id=data.id"; /** * 使用游标查询数据数据 * @return */ @Select(value = simpleQuery + " where status=1" + " order by news.id asc") @Options(fetchSize = Integer.MIN_VALUE)//mysql情况比较特殊,只能这样设置 Cursor<News> scrollResult(); }
service内使用
Cursor<News> cursor= repository.scrollResult(); Iterator<News> iter= cursor.iterator(); int count=0; while (iter.hasNext()){ System.err.println(iter.next().title); .......... }
mybatis游标查询 org.apache.ibatis.cursor.Cursor
先说使用场景:针对超大数据,内存不够存储数据。
假设有一个1千万的日志数据,需要将这一千万的数据,全部都清洗一遍,从每一条的数据中查询出匹配的有效数据,且不能修改原始数据。
第一种办法
一次性查出来,内存不够,而且会很慢,不可取。
这种方法就直接放弃。
第二种办法
分页查询, 每次查询1000条,每次处理完后,再分页查询。
这种分页查询,分页会很慢,除非是有索引id,通过顺序读取,还有可以优化一下。
第三种办法
游标查询 org.apache.ibatis.cursor.Cursor
数据库查询DAO
TempStudent 数据POJO
@Select(" SELECT * FROM temp_student ") Cursor<TempStudent> findListForCursor();
查询的service
@Transactional public void scanTempStudent() { Cursor<TempStudent> cursor = tempStudentDao.findListForCursor(); cursor.forEach(foo -> { System.out.println(foo.getId() + ":" + foo.getName()); }); }
特别注意,需要加上一个注解 Transactional, 事物的注解
为什么呢?
在取数据的过程中需要保持数据库连接,而 Mapper 方法通常在执行完后连接就关闭了,因此 Cusor 也一并关闭了,所以加上了事物保障就可以
Spring 框架当中注解使用的坑:只在外部调用时生效。在当前类中调用这个方法,依旧会报错。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。