jdbc和mybatis的流式查询使用方法

 更新时间:2021年11月01日 16:46:23   作者:我想问问天  
有些时候我们所需要查询的数据量比较大,但是jvm内存又是有限制的,数据量过大会导致内存溢出。这个时候就可以使用流式查询,本文就主要介绍了jdbc和mybatis的流式查询,感兴趣的可以了解一下

导语:

有些时候我们所需要查询的数据量比较大,但是jvm内存又是有限制的,数据量过大会导致内存溢出。这个时候就可以使用流式查询,数据一条条的返回,处理完一条在拿下一条数据,这样每次在内存里面的数据其实很小,不会导致内存溢出。

本文里面会讲到jdbc的流式查询和mybatis的流式查询。

jdbc流式查询:

jdbc的流式查询需要在生成PreparedStatement的时候设置三个参数。如下:

PreparedStatement stmt = jdbcTemplate.getDataSource().getConnection().prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);

主要使用到的是java.sql.Connection的prepareStatement方法。

PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException;

resultSetType和resultSetConcurrency我们要分别设置为ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY。

还有就是fetchSize设置为Integer.MIN_VALUE,一开始比较疑惑为啥是这个值。后来发现代码里面对这个值其实是有特殊处理的。

这个是com.mysql.cj.jdbc.StatementImpl的setFetchSize方法。

@Override
   public void setFetchSize(int rows) throws SQLException {
       synchronized (checkClosed().getConnectionMutex()) {
           if (((rows < 0) && (rows != Integer.MIN_VALUE)) || ((this.maxRows > 0) && (rows > this.getMaxRows()))) {
               throw SQLError.createSQLException(Messages.getString("Statement.7"), MysqlErrorNumbers.SQL_STATE_ILLcom.mysql.cj.jdbc.StatementImpl的方法EGAL_ARGUMENT, getExceptionInterceptor());
           }

           this.query.setResultFetchSize(rows);
       }
   }

resultSetType,有以下三种

/**
     * The constant indicating the type for a <code>ResultSet</code> object
     * whose cursor may move only forward.
     * @since 1.2
     */
    int TYPE_FORWARD_ONLY = 1003;

    /**
     * The constant indicating the type for a <code>ResultSet</code> object
     * that is scrollable but generally not sensitive to changes to the data
     * that underlies the <code>ResultSet</code>.
     * @since 1.2
     */
    int TYPE_SCROLL_INSENSITIVE = 1004;

    /**
     * The constant indicating the type for a <code>ResultSet</code> object
     * that is scrollable and generally sensitive to changes to the data
     * that underlies the <code>ResultSet</code>.
     * @since 1.2
     */
    int TYPE_SCROLL_SENSITIVE = 1005;
stmt = conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);

resultSetConcurrency有以下两种,流式查询要设置为只读的,数据不会被更新。

/**
     * The constant indicating the concurrency mode for a
     * <code>ResultSet</code> object that may NOT be updated.
     * @since 1.2
     */
    int CONCUR_READ_ONLY = 1007;

    /**
     * The constant indicating the concurrency mode for a
     * <code>ResultSet</code> object that may be updated.
     * @since 1.2
     */
    int CONCUR_UPDATABLE = 1008;

mybatis流式查询:

mapper中的代码:

@Select("select * from xxx order by xx desc")
@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = Integer.MIN_VALUE)
@ResultType(XxxObject.class)
void queryStreamResult(ResultHandler<XxxObject> handler);

在查询方法上加入注解@Options和@ResultType。设置参数不用多说和上面jdbc的底层是一样的,参数值也一样。

只不过设置了@ResultType告诉程序应该要返回什么类型的对象。还有这个ResultHandler其实就是Consumer的函数式接口用来处理每一条返回的数据。

具体方法中的代码:

@Override
   public Boolean dealDataList() {
       mapper.queryStreamResult(resultContext -> {
           dealSingleData(resultContext.getResultObject().getUid());
       });
       return true;
   }

这里怎么使用每一条返回的数据只要在resultContext使用ResultObject就可以拿到上面mapper设置的XxxObject对象进行操作了。

到此这篇关于jdbc和mybatis的流式查询使用方法的文章就介绍到这了,更多相关jdbc和mybatis流式查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot2.0如何自定义404页面渲染

    SpringBoot2.0如何自定义404页面渲染

    这篇文章主要介绍了SpringBoot2.0如何自定义404页面渲染问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Java设计模式之桥接模式详解(Bridge Pattern)

    Java设计模式之桥接模式详解(Bridge Pattern)

    桥接模式是一种结构型设计模式,旨在将抽象部分与其实现部分分离,从而使两者可以独立地变化,桥接模式通过组合关系代替继承关系,将抽象和实现解耦,使代码更具扩展性和维护性
    2025-02-02
  • 23种设计模式(2) java工厂模式

    23种设计模式(2) java工厂模式

    这篇文章主要为大家详细介绍了23种设计模式之java工厂模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • 基于SpringMVC @RequestMapping的参数和用法

    基于SpringMVC @RequestMapping的参数和用法

    这篇文章主要介绍了SpringMVC @RequestMapping的参数和用法解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • 在Java生产环境下进行性能监控与调优的详细过程

    在Java生产环境下进行性能监控与调优的详细过程

    在Java生产环境下进行性能监控与调优是一个复杂但重要的过程,它涉及到多个方面,包括代码分析、JVM监控、线程管理、垃圾收集优化、内存管理、数据库交互等,下面我将提供一个详细的概述和示例代码,需要的朋友可以参考下
    2025-02-02
  • 一个简单的java学生寝室查询系统

    一个简单的java学生寝室查询系统

    这篇文章主要为大家详细介绍了一个简单的java学生寝室查询系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • Java Float 保留小数位精度的实现

    Java Float 保留小数位精度的实现

    这篇文章主要介绍了Java Float 保留小数位精度的实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Spring Cloud基于zuul实现网关过程解析

    Spring Cloud基于zuul实现网关过程解析

    这篇文章主要介绍了Spring Cloud基于zuul实现网关过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • Java 处理超大数类型之BigInteger案例详解

    Java 处理超大数类型之BigInteger案例详解

    这篇文章主要介绍了Java 处理超大数类型之BigInteger案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • Spring6.x对调度和异步执行的注解支持示例详解

    Spring6.x对调度和异步执行的注解支持示例详解

    这篇文章主要为大家介绍了Spring6.x对调度和异步执行的注解支持示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11

最新评论