java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > mybatis对大量数据的游标查询

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 框架当中注解使用的坑:只在外部调用时生效。在当前类中调用这个方法,依旧会报错。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文