SpringBoot+Mybatis流式查询

前言

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

如果没有使用流式查询,我们想要从数据库取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毫秒

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值