查看原文
其他

【267期】面试官:Mybatis 如何实现流式读取 MySQL 大数据量记录?

Java精选 2022-08-09

点击上方“Java精选”,选择“设为星标”

别问别人为什么,多问自己凭什么!

下方有惊喜,留言必回,有问必答!

每一天进步一点点,是成功的开始...

背景

最近公司提了个需求,说公司的旧系统的报表导出的时候,数据量超过一万就导不出来了。经过分析,是旧系统做了限制。在更新的时候,查看了导出时虚拟机GC情况,发现原先程序执行时,内存激增,经过Google决定采用流式读取对sql进行优化。

JDBC三种读取方式

  1. 一次全部(默认):一次获取全部。
  2. 流式:多次获取,一次一行。
  3. 游标:多次获取,一次多行。

mybatis默认采取第一种。

开发环境

jdk1.8 、intellij IDEA 2018

mybatis 3 、 springMVC 、Spring 4

实现步骤

实现流式读取的方式不止一种,但是我只能说我解决的这种,对不起,我不是大神级的。

这里采用的 controller、service、dao分层开发

  • 在service层调用dao接口是,增加一个回调参数ResultHandler<>
  • 对应的dao接口返回值为void
  • mapper 填写 parameterType、resultMap、resultSetType=“FORWARD_ONLY”fetchSize="-2147483648"

为什么dao返回值为void还要在mapper写resultMap?因为回调要用你的resultMap处理,但是不应该返回给service,因为回调处理好了。

推荐下几个月熬夜整理的近 10000+ 面试资料大全:https://gitee.com/yoodb/eboo‍ks

示例代码

controller层:

@RequestMapping("/export")
  public void export(Vo vo, String props,
      HttpServletResponse response) 
{

    //.......
      list = ossVipCustomService.selectForwardOnly(vo, Order.build());
    //......
  }

service层:(重点)

public List<Bo> selectForwardOnly(Vo vo, Order order) {
     final List<Bo> list = new ArrayList<>();
    mapper.selectForwardOnly(vo, order, new ResultHandler<Bo>() {
      @Override
      public void handleResult(ResultContext<? extends Bo> resultContext) {
        /**回调处理逻辑 */
        list.add(resultContext.getResultObject());
      }
  });
    return list;
  }

dao层:(重点)

  /**
   * 流式读取数据
   * @param vo 查询对象
   * @param order 排序
   * @param ossVipCustomerBoResultHandler 回调处理
   */

  void selectForwardOnly(@Param("record") Vo vo, @Param("order") Order order,
      ResultHandler<Bo> handler)
;

mapper:(重点)

<select id="selectForwardOnly"
  parameterType="com.*.Vo" resultMap="GetListBo"
    resultSetType="FORWARD_ONLY" fetchSize="-2147483648">
    SELECT
    *
    FROM
    customer
  </select>

个人原因:删除非关键部分代码。你肯定看的懂得。

心路历程

Google了好久的一个原因,就是因为dao接口不应该返回值的。还麻烦了老大过来看了一眼。

还有就是google出来的那些,要改框架配置的,我的确跟着改了,改了mysql连接参数,还有mybatis setting的配置。嗯,没用。

版权声明:本文为CSDN博主「suveng」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

https://suveng.blog.csdn.net/article/details/85100239

公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!

------ THE END ------

精品资料,超赞福利!


3000+ 道面试题在线刷,最新、最全 Java 面试题!

期往精选  点击标题可跳转

【260期】PageHelper 使用 ThreadLocal 的线程复用问题,你用对了吗?

【261期】为什么 BigDecimal 类不能使用 equals() 方法做等值比较?

【262期】面试官:jwt 是什么?java-jwt 呢?懵逼了。。。

【263期】面试官问:假设有一千万数据,怎么快速查询?

【264期】面试官问:Spring Boot 启动时自动执行代码方式有哪几种?解释一二!

【265期】面试官:列举 8 种 Docker 应用场景,你对哪些有了解?

【266期】面试官问:为什么 SQL 要尽量避免使用 IN 和 NOT IN?

【267期】Spring Boot 如何整合 WebSocket 实现群聊,一对一聊天?

 技术交流群!

最近有很多人问,有没有读者交流群!想知道如何加入?方式很简单,兴趣相投的朋友,只需要点击下方卡片,回复“加群”,即可无套路入交流群!

文章有帮助的话,在看,转发吧!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存