《mybatis》--大数据量查询解决方案

阿丹-需求/场景:

之前写百万以及千万的导出数据的时候,对于将数据写道csv文件并压缩这里没有什么大问题了,但是出现了其他问题为:

1、我们需要将数据从数据库中拿出来,并且在进行装配的时候出现了一些问题。

2、对于整体内存安全来说,如果直接将数据从数据库中拿出来百万级别以上的数据对于内存是非常不友好的。当问题出现比较大的时候会直接触发GC,造成瘫痪。

目前开发以及项目测试的是更多的使用mybatis来进行开发的,所以本文章讨论以及解决的的就是如何使用mybaits来解决流式查询并单条处理的问题。

解决方案:

使用MyBatis查询超大数据时,为了避免内存溢出(OOM, OutOfMemoryError)问题,可以采用以下几种解决方案:

  1. 流式查询 (Stream Result)

    • MyBatis 提供了<select>标签的resultType="void"配合<resultMap>useResultHandler="true"属性来实现流式查询。通过定义一个ResultHandler接口的实现类,MyBatis会在遍历结果集的过程中逐行调用处理方法,这样每处理一行就释放一行的数据,从而避免一次性加载所有数据到内存中。

    在Java代码中:

    复制代码
    sqlSession.select("streamingQuery", parameter, new ResultHandler() {
        @Override
        public void handleResult(ResultContext context) {
            Object object = context.getResultObject();
            // 处理单行数据并确保及时释放资源
        }
    });
  2. 分页查询 (Pagination)

    • 如果业务允许,对数据进行分页查询是最常见的做法,每次仅从数据库获取一部分数据。
    • 在MyBatis中可以通过动态SQL或者参数绑定实现分页,例如使用PageHelper等第三方分页插件。
  3. 游标查询 (Cursor)

    • 对于支持游标的数据库(如Oracle、PostgreSQL等),可以利用数据库层面的游标特性,在不关闭连接的情况下逐步读取结果集。
    • MyBatis 3.4.6版本及更高版本直接支持JDBC ResultSet类型的返回值,结合Statement#setFetchSize()方法可以实现类似游标的效果,有效地控制内存占用。
  4. 优化SQL查询

    • 减少不必要的字段查询,只取出需要的列。
    • 使用JOIN或子查询时,注意是否能进一步优化SQL语句以减少结果集大小。
    • 避免在应用层做大量计算和数据转换,尽量让数据库完成复杂过滤和聚合操作。
  5. 分布式处理或批处理

    • 如果数据量实在太大,可以考虑将任务分解为多个小任务,每个任务处理部分数据,然后汇总结果。
  6. 数据库端缓存与分片策略

    • 在数据库层面对大表进行分区或索引优化,减少单次查询的数据量。

选择哪种方案取决于具体的应用场景、数据库类型以及系统架构设计。流式查询通常是在内存限制严格且必须一次性处理大量数据时的最佳实践。

相关推荐
不谈恋爱的猫1 天前
redis哨兵模式
数据库·redis·mybatis
步行cgn1 天前
JNDI 详解:它是什么,为什么用,怎么用?
mybatis
paopaokaka_luck1 天前
基于springboot3+vue3的云南本土影视文旅推荐平台(协同过滤算法、Echarts图形化分析)
前端·spring boot·学习·算法·echarts·mybatis
黄毛火烧雪下1 天前
2026 Java后端面试题总结(持续更新):Spring、MyBatis、Redis、MySQL、多线程
java·spring·mybatis
paopaokaka_luck1 天前
基于springboot3+vue3的企业考勤管理系统(部门树递归、Echarts图形化分析)
开发语言·spring boot·学习·echarts·mybatis·需求分析·代码规范
SQL-First布道者2 天前
⚡ Spring JDBC 完整体系 · 第 8 讲 · 查询四象限完备
java·spring boot·后端·spring·mybatis·spring jdbc
乐观的Terry3 天前
11、发布系统-用户认证与权限体系
java·spring boot·spring·spring cloud·mybatis
步行cgn3 天前
carList.forEach(System.out::println)
java·开发语言·mybatis
豆角焖肉4 天前
MyBatis多表关联查询(一对多/多对一/多对多)
mybatis·一对多·多表设计·多对多·一对一·多对一
学Linux的语莫4 天前
Redis 的两种持久化方式:RDB 和 AOF,一次讲懂
数据库·redis·mybatis