jdbc和mybatis的流式查询使用方法
作者:我想问问天 发布时间:2023-08-24 15:39:25
导语:
有些时候我们所需要查询的数据量比较大,但是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对象进行操作了。
来源:https://juejin.cn/post/7025246513622155272


猜你喜欢
- 一、Servlet概述1.sun公司提供的动态web资源开发技术。本质是上一段java小程序,要求这个小程序必须实现Servlet接口,以便
- 一、下载客户端代码package javadownload; import java.io.ByteArrayOutputStream; i
- IDEA maven没有dependenciesIDEA导入新项目没有dependencies跟plugins如图:解决办法网上方法很多,重
- 1.内部类概念及分类将一个类定义在另一个类的内部或者接口内部或者方法体内部,这个类就被称为内部类,我们不妨将内部类所在的类称为外围类,除了定
- 前言C#基于NAudio工具对Wav音频文件进行剪切,将一个音频文件剪切成多个音频文件注:调用方法前需要导入NAudio.dll或者在NuG
- 以下四种方式:1.继承Thread类,重写run方法2.实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象
- 本文实例为大家分享了Springboot整合pagehelper分页展示的具体代码,供大家参考,具体内容如下一、添加依赖查找maven中pa
- 前言本文提供三种不同的解决方式,也是三种不同的情况和思路我的问题是在springboot整合了xxl-job一段时间后出现的。如果你程序里集
- android跑马灯出现重复跳动、不滚动问题,本文给出解决方案,供大家参考。原因:页面有View被重新绘制了、焦点被抢占例如:1、TextV
- C# using 三种使用方式介绍1.using指令。using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的
- Synchronized实现可见性原理可见性要实现共享变量的可见性,必须保证两点:线程修改后的共享变量值能够及时从工作内存刷新到主内存中其他
- 目录一、什么是反射:二、反射的原理:三、反射的优缺点:四、反射的用途:五、反射机制常用的类:六、反射的基本使用:1、获得Class:主要有三
- 本文实例讲述了Android实现GridView中ImageView动态变换的方法。分享给大家供大家参考。具体如下:使用YY影音的时候,发现
- 一、电量统计模块概述耗电信息在设置 -> 电量中能够非常直观的看到。注意,Android 所有功耗统计都是通过代码估算,没有集成电路参
- 在新版的AndroidStudio3.6 中,在项目的包下新建 activity 时,一般会同时生成对应的java和xml文件,例如新建 M
- 本文实例讲述了Android7.0开发实现Launcher3去掉应用抽屉的方法。分享给大家供大家参考,具体如下:年初做过一个项目,有一个需求
- 通过@Query注解支持JPA语句和原生SQL语句在SpringData中们可是使用继承接口直接按照规则写方法名即可完成查询的方法,不需要写
- 人人客户端有一个特效还是挺吸引人的,在主界面手指向右滑动,就可以将菜单展示出来,而主界面会被隐藏大部分,但是仍有左侧的一小部分同菜单一起展示
- 需求:将 一个容器List<Bean> 按照一定的字段进行分组,分组过后的值为特定的BEAN 里面的属性例如:假定有这样一个Be
- SimpleDateFormat类:SimpleDateFormat是-一个以与语言环境有关的方式来格式化和解析日期的具体类。进行格式化(日