背景描述
最近在做一个项目,需要把大批量(100列,100w+行)的数据导到Excel中,在查数据时直接OOM。想过用分页查询或者流式查询来解决该问题,考虑到分页查询的效率问题,决定先用流式查询来处理看看效果。在此记录一下流式查询的使用过程。
前言
流式查询:指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果。流式查询的好处是能够降低内存使用。
mybatis使用步骤
1.定义Mapper
void findList(Map<String,String> params, ResultHandler<CalcRstDtl> handler);
params: 查询参数;
ResultHandler: 回调接口,也就是从游标中获得一条数据就会回调接口中的方法。
2.mapper.xml文件配置
<selsect id="findList" parameterType="java.util.Map" resultMap = "com.cnlab.entity.CalcRstDtl" fetchSize="1000">
SELECT
ID, NUM
FROM
T_D_CALC_RST_DTL
<where>
<if test="dealerName != null and dealerName != ''">
AND DEALER_NAME like CONCAT('%',CONCAT(#{dealerName},'%'))
</if>
</where>
</select>
fetchSize:select语句需要增加fetchSize属性,底层是调用jdbc的setFetchSize方法,查询时从结果集里面每次取设置的行数,循环去取,直到取完。默认size是0,也就是默认会一次性把结果集的数据全部取出来,当结果集数据量很大时就容易造成内存溢出。
3. service 中调用 Mapper定义的方法
其他业务代码就不展示,直接展示在server中的使用
@Override
public void calcRstExport(Map<String,String> params){
//流式查询调用
calcRstMapper.findList(params, resultContext ->{
//获取返回的第几条数据
int resultCount = resultContext.getResultCount();
//获取当前数据信息
CalcRstDtl dtl = (CalcRstDtl)resultContext.getResultObject();
// ****其他业务信息就不过多的展示****
});
}
总结
查询效率还不错,至少还不会OOM了。
以上就是本次使用 mybatis 流式查询的历程,新手小白第一次上路,还有很多不足之处还请大佬们多多指教。