文章目录
当一次性从数据库中查询大量数据时,由于结果集非常大,容易导致内存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.