文章目录


当一次性从数据库中查询大量数据时,由于结果集非常大,容易导致内存OOM,此时可以采用 分页查询或者可以利用 Mybatis 中的 ResultHandler 来实现流式输出,分页查询前面章节已经介绍过了,下面看下mybatis如何利用流式输出的,流式输出就像游标一样,一条条的处理目标结果集。

Mybatis 中的 ResultHandler 相当于数据结果集的处理器,它是一个回调函数(Callback),用来处理每一行数据的结果,这个回调函数可以在查询结果处理到一定量时触发,对结果集数据进行定制化处理。

ResultHandler 的使用可以大幅提升数据处理的效率,当我们需要处理大量的数据时,一般会使用 ResultHandler 来进行结果的处理,避免一次查询就全部返回结果,浪费内存资源或造成 OOM。

下面我们看下如何利用ResultHandler一条一条的数据处理

还是以下面的PERSON表为例
在这里插入图片描述
我们要查询persion_id大于多少的数据,对应的mapper文件如下所示

<resultMap id="resultMap1" type="com.lzj.bean.Person">
    <result column="PERSON_ID" property="id"></result>
    <result column="PERSON_NAME" property="name"></result>
    <result column="PERSON_AGE" property="age"></result>
</resultMap>
<select id="select1" resultMap="resultMap1">
    select * from PERSON where PERSON_ID > #{personId}
</select>

对应的Dao接口为

public interface PersonDao {
    public List<Person> select1(int personId);
}

下面重点来了,我们要定义自己的ResultHandler,用来定制化的处理每条数据,当然我们只是简单的输出每条数据

import com.lzj.bean.Person;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;

public class MyResultHandler implements ResultHandler<Person> {

    /*定制化处理每条数据,此处只是简单的输出*/
    @Override
    public void handleResult(ResultContext<? extends Person> resultContext) {
        Person person = resultContext.getResultObject();
        System.out.println(person);
    }
}

最后执行下面的测试案例

public void sqlSessionTest6(){
    SqlSessionFactory factory = mybatisUtil.getFactory();
    SqlSession sqlSession = factory.openSession(true);  //true表示自动提交
    sqlSession.select("com.lzj.dao.PersonDao.select1", 5, new MyResultHandler());
    sqlSession.close();
}

输出结果如下所示,从日志中可以看出,查出persion_id>5的数据总共有4条数据,分别通过我们定制的MyResultHandler的方法处理了每条数据。

Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 1114681666.
==>  Preparing: select * from PERSON where PERSON_ID > ? 
==> Parameters: 5(Integer)
<==    Columns: person_id, person_name, person_age
<==        Row: 6, Bob, 25
Person{id=6, name='Bob', age=25}
<==        Row: 7, Jimi, 24
Person{id=7, name='Jimi', age=24}
<==        Row: 8, Dobu, 40
Person{id=8, name='Dobu', age=40}
<==        Row: 9, Lee, 33
Person{id=9, name='Lee', age=33}
<==      Total: 4
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4270b142]
Returned connection 1114681666 to pool.
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐