Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MyBatis中使用流式查询避免数据量过大导致OOM

MyBatis中使用流式查询避免数据量过大导致OOM

作者头像
终码一生
发布于 2022-04-15 04:30:44
发布于 2022-04-15 04:30:44
1.4K00
代码可运行
举报
文章被收录于专栏:终码一生终码一生
运行总次数:0
代码可运行

今天mybatis查询数据库中大量的数据,程序抛出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java.lang.OutOfMemoryError: Java heap space

看下日志,是因为一次查询数据量过大导致JVM内存溢出了,虽然可以配置JVM大小,但是指标不治本,还是需要优化代码。网上查看大家都是流式查询,这里记录下解决的过程。

1

Mapper.xml配置

select语句需要增加fetchSize属性,底层是调用jdbc的setFetchSize方法,查询时从结果集里面每次取设置的行数,循环去取,直到取完。默认size是0,也就是默认会一次性把结果集的数据全部取出来,当结果集数据量很大时就容易造成内存溢出。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<select id="listTaskResultIpInfo" fetchSize="1000" resultType="String">
    select info from task_result_info where project_id = #{projectId} and task_id = #{taskId}
</select>

注意:此时需要在mysql连接URL中增加useCursorFetch=true。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useCursorFetch=true

2

自定义ResultHandler

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * Created by bo on 2019/8/23.
 * MyBatis中使用流式查询避免数据量过大导致OOM
 */
public class ResultInfoHandler implements ResultHandler<CustTaskResultInfo> {
    // 存储每批数据的临时容器
    private List<CustTaskResultInfo> resultInfoList = new ArrayList<>();
 
    public List<CustTaskResultInfo> getResultInfoList() {
        return resultInfoList;
    }
 
    @Override
    public void handleResult(ResultContext<? extends CustTaskResultInfo> resultContext) {
        CustTaskResultInfo custTaskResultInfo = resultContext.getResultObject();
        resultInfoList.add(CustTaskResultInfo);
    }
}

3

spring中配置sqlSessionTemplate

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
    <!-- mapper扫描 -->
    <property name="mapperLocations" value="classpath:mybatis/mapper/*/*.xml"/>
</bean>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg index="0" ref="sqlSessionFactory" />
</bean>

4

service中使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
  
public List<CustTaskResultInfo> listTaskResultInfo(Long projectId, Long taskId) {
    Map<String, Object> param = new HashMap<>();
    param.put("projectId", projectId);
    param.put("taskId", taskId);
    ResultInfoHandler handler = new ResultInfoHandler();
    sqlSessionTemplate.select("com.iie.cyberpecker.dao.custom.CustTaskResultInfoMapper.listTaskResultInfo", param, handler);
    return handler.getResultInfoList();
}

5

疑问

上面这种方案必须要定义一个sqlSessionTemplate,我想着能不能直接在mapper.xml中配置,网上说的是这样实现。

参考:

https://blog.csdn.net/weixin_43221845/article/details/84871362

https://www.jianshu.com/p/0339c6fe8b61

https://stackoverflow.com/questions/28413717/how-to-connect-a-resulthandler-in-mybatis-mapper-xml

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 终码一生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
MyBatis中使用流式查询避免数据量过大导致OOM
其中fetchSize="-2147483648",Integer.MIN_VALUE=-2147483648
加多
2018/09/06
8.2K0
MyBatis中使用流式查询避免数据量过大导致OOM
Mybatis 流式读取大量MySQL数据
最近公司提了个需求 ,说公司的旧系统的报表导出的时候,数据量超过一万就导不出来了。经过分析,是旧系统做了限制。在更新的时候,查看了导出时虚拟机GC情况,发现原先程序执行时,内存激增,经过Google决定采用流式读取对sql进行优化。
搜云库技术团队
2023/03/15
3.8K0
Mybatis 流式读取大量MySQL数据
mybatis 流式读取大量MySQL数据
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
suveng
2019/09/18
7.4K0
mybatis 流式读取大量MySQL数据
mybatis原理,配置介绍及源码分析
mybatis是一款优秀的持久层框架,支持定制SQL语句,避免了几乎所有JDBC代码和手动设置参数,结果集获取
kinnylee
2020/10/15
1.3K0
mybatis原理,配置介绍及源码分析
每天用Mybatis,但是Mybatis的工作原理你真的知道吗?
近来想写一个mybatis的分页插件,但是在写插件之前肯定要了解一下mybatis具体的工作原理吧,于是边参考别人的博客,边看源码就开干了。
程序员追风
2019/11/08
2980
每天用Mybatis,但是Mybatis的工作原理你真的知道吗?
Mybatis的基本使用方法
  XML配置文件的名称通常为mybatis-config.xml,内容基本格式如下:
林老师带你学编程
2019/05/26
5960
三万字带你彻底吃透MyBatis源码!!
作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。为使更多童鞋受益,现给出开源框架地址:
冰河
2021/01/12
7040
三万字带你彻底吃透MyBatis源码!!
长文警告!springboot mybatis 源码
springboot-mybatis 整合了 mybatis 对数据库的访问操,其为我做了很好的封装,开箱即用。只要在项目中引入 maven的依赖,打上 MapperScan 的注解就可以进入我们的业务开发。
用户5546570
2020/11/12
7290
MyBatis Plus 解决大数据量查询慢问题
在实际工作中当指定查询数据过大时,我们一般使用分页查询的方式一页一页的将数据放到内存处理。但有些情况不需要分页的方式查询数据或分很大一页查询数据时,如果一下子将数据全部加载出来到内存中,很可能会发生OOM(内存溢出);而且查询会很慢,因为框架耗费大量的时间和内存去把数据库查询的结果封装成我们想要的对象(实体类)。
捡田螺的小男孩
2023/02/22
1.8K0
MyBatis Plus 解决大数据量查询慢问题
mybatis解读篇
传统方式需要加载驱动,声明sql等操作,而现在的框架都像上面一样进行了各种封装,使得我们使用更加方便,下面来看看mybatis的方式。
用针戳左手中指指头
2021/01/29
9210
mybatis解读篇
MyBatis源码分析一:核心组件
前面一篇文章MyBatis3使用 讲解了MyBatis的基本使用,这篇介绍MyBatis的核心组件,让我们从整体上了解MyBatis的组成。
心平气和
2021/01/13
4980
MyBatis源码分析一:核心组件
Mybatis源码分析
variables:用来存放 properties 节点中解析出来的 Properties 数据。
用户7353950
2022/06/23
4880
Mybatis源码分析
一分钟进入mybatis的世界
mybatis是一款优秀的持久层框架, 通过配置mybatis-config.xml和mapper.xml就可以轻松完成ORM工作. 在当前流行JavaCodeConfig的情况下, 这些配置项又是
一个架构师
2022/06/20
1940
Spring Boot : Mybatis 执行原理分析
计算机的基本工作就是存储和计算,而MyBatis是存储领域的利器。MyBatis的基本工作原理就是:先封装SQL,接着调用JDBC操作数据库,最后把数据库返回的表结果封装成Java类。
Freedom123
2024/03/29
3410
Spring Boot : Mybatis 执行原理分析
MyBatis-4.Java API
MyBatis 的主要 Java 接口就是 SqlSession。可以通过这个接口来执行命令,获取映射器和管理事务。 SqlSessions 是由 SqlSessionFactory 实例创建的。SqlSessionFactory 对象包含创建 SqlSession 实例的所有方法。而 SqlSessionFactory 本身是由 SqlSessionFactoryBuilder 创建的,它可以从 XML、注解或手动配置 Java 代码来创建 SqlSessionFactory。
悠扬前奏
2019/05/30
8900
MyBatis 源码
MyBatis 工作流程:应用程序首先加载mybatis-config.xml 配置文件,并根据配置文件的内容创建 SqlSessionFactory 对象;然后,通过 SqlSessionFactory 对象创建 SqlSession 对象,SqlSession 接口中定义了执行 SQL 语句所需要的各种方法。之后,通过 SqlSession 对象执行映射配置文件中定义的 SQL 语句,完成相应的数据操作。最后通过 SqlSession 对象提交事务,关闭 SqlSession 对象,整个过程具体实现如下:就按照下面的流程进行源码分析
Java架构师必看
2021/05/14
3320
MyBatis 源码
浅谈Mybatis持久化框架在Spring、SSM、SpringBoot整合的演进及简化过程
最近开始了SpringBoot相关知识的学习,作为为目前比较流行、用的比较广的Spring框架,是每一个Java学习者及从业者都会接触到一个知识点。作为Spring框架项目,肯定少不了与数据库持久层的整合。我们在学习Java初始就被灌输SSM框架(Spring、SpringMVC、Mybatis),我们大概也只是知道Mybatis是与数据库打交道的,但这也只是名词上的理解。
Java_老男孩
2020/08/11
5700
面试官:从 MySQL 数据库里读取 500w 数据行进行处理,应该怎么做更效益化?
由于现在 ORM 框架的成熟运用,很多小伙伴对于 JDBC 的概念有些薄弱,ORM 框架底层其实是通过 JDBC 操作的 DB
Java程序猿
2021/05/19
2.3K0
2021年了,该懂Mybatis是怎么实现的了!
想要实现一套增删改查是一件极其简单的事情,让人困惑的是UserMapper是一个接口,为什么可以被注入到UserService中,为什么调用UserMapper接口中的方法就可以执行想要执行的SQL,从而完成我们想要的结果。
java进阶架构师
2021/01/05
7330
MyBatis官方文档-Java API
既然你已经知道如何配置 MyBatis 和创建映射文件,你就已经准备好来提升技能了。MyBatis 的 Java API 就是你收获你所做的努力的地方。正如你即将看到的,和 JDBC 相比,MyBatis 很大程度简化了你的代码并保持代码简洁,容易理解并维护。MyBatis 3 已经引入了很多重要的改进来使得 SQL 映射更加优秀。
Java架构师必看
2020/04/10
1.7K0
相关推荐
MyBatis中使用流式查询避免数据量过大导致OOM
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验