龙空技术网

MyBatis-三种流式查询方法千万条数据不用分页

微笑花猫cat 2359

前言:

当前兄弟们对“isajava”大致比较着重,朋友们都需要知道一些“isajava”的相关内容。那么小编同时在网上搜集了一些对于“isajava””的相关文章,希望朋友们能喜欢,大家一起来学习一下吧!

流式查询指的是:查询结束后不是返回一个汇合而是返回一个迭代器,利用每次从迭代器取一条查问后果。如果没有流式查询,想要从数据库取 1000 万条记录而又没有足够的内存时,就不得不分页查询。

MyBatis 流式查询接口Cursor提供了三个方法:

isOpen():用于在取数据之前判断 Cursor 对象是否是关闭。isConsumed():用于判断查询结果是否全部取完。getCurrentIndex():返回已经获取了多少条数据。

因为 Cursor 实现了迭代器接口,因而在理论应用当中,从 Cursor 取数据非常简单:

cursor.forEach(rowObject -> {…})。

例子:

1、Dao:如下图在mapper里有一个返回结果用Cursor封装的queryPage方法

@Mapperpublic interface TmMaterialLackRecordDao extends BaseMapper<TmMaterialLackRecord> {          Cursor<TmMaterialLackRecordVo> queryPage(@Param("pageBo") TmMaterialLackRecordPageBo pageBo);}

2、Dao.xml:TmMaterialLackRecordDao对应的xml文件里定义具体的查询sql

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ";><mapper namespace="com.asm.abc.dao.TmMaterialLackRecordDao">    <select id="queryPage" resultType="com.asm.abc.vo.TmMaterialLackRecordVo">        select p.saas_id,p.plant_id from t_tm_material_lack_record p        where p.is_del !=1        <if test="pageBo.saasId !=null and pageBo.saasId!=''">            and p.saas_id = #{pageBo.saasId}        </if>        <if test="pageBo.plantId !=null and pageBo.plantId != 0 ">            and p.plant_id = #{pageBo.plantId}        </if>        order by p.check_date_time desc    </select></mapper>

3、service层调用Dao层查询,@SneakyThrows注解是抛出异常的意思,lombok的注解

@SneakyThrows@Transactionalpublic void exportMaterialLackRecord(TmMaterialLackRecordPageBo pageBo) {        List<TmMaterialLackRecordVo> list = new ArrayList<>();    try (Cursor<TmMaterialLackRecordVo> export = this.baseMapper.queryPage(pageBo)) {        export.forEach(foo -> list.add(foo));    }}

注意:@Transactional是为了保证数据库长连接,不然会抛出java.lang.IllegalStateException: A Cursor is already closed。另外还有两种实现方式TransactionTemplate和SqlSessionFactory可以自行验证。@Transactional 注解标注的方法只能被不同的类来调用,在当前类里的其他方法调用该注解标注的方法会导致事务失效。

标签: #isajava