<>前言

流式查询指的是查询成功后不是返回一个集合,而是返回一个迭代器,应用每次从迭代器取一条查询结果。流式查询的好处是能降低内存的使用。

如果没有使用流式查询,我们想要从数据库取1000万条记录而又没有足够的内存时,就不得不分页查询,而分页查询效率取决于表设计,如果设计得不好是,就无法高效的分页查询。因此流式查询是一个数据库访问框架必须具备的功能。

流式查询的过程当中,数据库连接是保持打开状态的,因此要注意的是:执行一个流式查询后,数据库访问框架就不负责关闭数据库连接了,需要应用在取完数据后自己关闭。

SpringBoot中应用

* UserMapper /** * 流式查询所有user * @return 返回的类型是游标类型 *
当查询百万级的数据的时候,使用游标可以节省内存的消耗,不需要一次性取出所有数据,可以进行逐条处理或逐条取出部分批量处理。 */ Cursor<User>
selectAll2(); //返回的是游标对象类型
* UserMapper.xml
在Mapper映射文件的标签中加入fetchSize=100
。因为mybatis默认是把所有数据全部查询出后返回,这样容易造成OOM问题(内存溢出),这时,我们设置一下fetchSize,设置每次查询出多少条数据,之后再执行next方法,读取下一批数据,这样每次查询出来一点,就处理一点,就不容易造成OOM问题了。
<!--加上fetchSize--> <select id="selectAll2" resultType="
com.age.batch.batchuser.entity.User" fetchSize="100"> select
id,username,age,sex,address from user</select>
* UserService /** * 流式查询所有user * @return */ Cursor<User> selectAdd2();
* UserServiceImpl /** * 流式查询所有user * @return */ @Override public Cursor<User>
selectAdd2() { return userMapper.selectAll2(); }
* controller @ApiOperation("流式查询所有user,测试查询时间") @GetMapping("/selectall2")
@Transactional
//注意要使用@Transactional注解来维持数据库连接,否则当recordMapper查询结束后数据库连接就会断开,Cursor就取不到数据了
public void selectAll2(){ Cursor<User> users = userService.selectAdd2(); users.
forEach(user -> System.out.println(user)); }
5000条数据,普通查询下的耗时为1366毫秒,流式查询下的耗时为76毫秒

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信