mysql数据库流式查询

本文介绍了MySQL数据库的流式查询以避免大量数据导致的内存溢出问题。通过JDBC编程示例展示了如何设置PreparedStatement的fetchSize为Integer.MIN_VALUE实现流式读取,以及在MyBatis中使用MyBatisCursorItemReader和ResultHandler进行流式处理的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.为什么使用流式查询?

普通查询方式:

1)JVM进程内数据库线程池,某一线程执行查询时,调用mysql驱动程序。

2)mysql驱动向mysql服务器发起TCP请求,服务器端根据条件查询匹配的数据,然后通过TCP链接发送到MySQL驱动。

3)mysql驱动把符合条件的数据缓存到驱动内存中,待数据发送结束,返回给应用程序缓存数据。

所以,mysql驱动内存就可能在访问大量数据(使用场景)时发生OOM。

2.JDBC编程中mysql流式查询

        为了有效避免OOM,mysql客户端流式查询不会同时把服务器端的所有符合条件的数据缓存起来,而是一部分一部分的把服务器端返回的数据返回给应用程序层。

代码示例:

public void selectData(String sqlCmd,) throws SQLException {

    validate(sqlCmd);

    Connection conn = null;
    PreparedStatement stmt = null;
    ResultSet rs = null;

    try {

        conn = petadataSource.getConnection();
        
        stmt = conn.prepareStatement(sqlCmd, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
        stmt.setFetchSize(Integer.MIN_VALUE);
            
        rs = stmt.executeQuery();

        try {
            while(rs.next()){
                try {
                    System.out.println("one:" + rs.getString(1) + "two:" + rs.getString(2) + "thrid:" + rs.getString(3));
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        } finally {
            close(stmt, rs, conn);

        }
}

3.Mybatis 中使用流式查询

①.MyBatisCursorItemReader

1)配置文件:注入MyBatisCursorItemReader

<bean id="myMyBatisCursorItemReader" class="org.mybatis.spring.batch.MyBatisCursorItemReader">

<property name="sqlSessionFactory" ref="sqlSessionFactory" />

<property name="queryId" value=" (mapper文件中查询ID)" />

</bean>

2)mapper文件配置:

<select id="queryId" fetchSize="-2147483648" ../>

3) 代码使用:

Map<String, Object> param = new HashMap<String, Object>();
param.put("oredCriteria", example.getOredCriteria());
// 设置参数
myMyBatisCursorItemReader.setParameterValues(param);
// 创建游标
myMyBatisCursorItemReader.open(new ExecutionContext());
//使用游标迭代获取每个记录
Long count = 0L;
Bean bean;
while ((bean = myMyBatisCursorItemReader.read()) != null) {
    System.out.println(JSON.toJSONString(bean));
    ++count;
}

②.ResultHandler

1)配置mapper 的fetchSize属性

2)代码使用

SqlSession session = sqlSessionFactory.openSession();
session.select("selectByExample", example, new ResultHandler() {
    @Override
    public void handleResult(ResultContext resultContext) {
        Bean bean = (Bean) resultContext.getResultObject();
        System.out.println(resultContext.getResultCount());
        System.out.println(JSON.toJSONString(bean));
    }
});

 

PS:

参考:

1.转载自并发编程网 – ifeve.com 本文链接地址: MySQL中流式查询使用

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值