一、前言
MySQL 是目前使用比较广泛的关系型数据库,而从数据库里面根据条件查询数据到内存的情况想必大家在日常项目实践中都有使用。
当指定条件的数据量特别大时候一般是通过分页的方式在前端页面通过 Tag 标签一页页的加载数据到内存;但是有些情况下却不需要用户切换 Tag 标签的方式一页页的加载数据,这时候如果一下子全部把数据加载内存,就有可能会导致 OOM,虽然这时候可以通过程序控制分页查询,但是每次查询时候数据库都需要把所有符合条件的数据查询出来然后根据当前页的返回来返回指定的页,这无疑加重了 MySQL 服务器不必要的开销。
其实在 MySQL 中提供了流式查询,这允许把符合条件的数据一部分一部分的加载到内存,本 Chat 就来具体讲解如何在 MySQL中使用流式查询:
使用流式查询前,我们是如何在 MySQL 中进行查询数据的,整个过程发生了什么?
如何使用 JDBC 编程方式在 MySQL 中使用流式查询?
如何在 Mybatis 中使用 MyBatisCursorItemReader 进行流式查询?
如何在 Mybatis 中使用 ResultHandler 进行流式查询?
什么是客户端流式查询和服务器端流式查询?
二、使用 MySQL 进行数据查询时候发生了什么
首先我们来看看在不用流式查询时候当我们发一个数据库查询到底发生了什么?普通查询下一般是下面结构:
public void selectData(String sqlCmd, ProcessCallback callBack) throws SQLException {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sqlCmd);
rs = stmt.executeQuery();
// 执行回调
callBack.doAction(rs);
} finally {
close(stmt, rs, conn);
}
}
public static void main(String[] args) throws Exception {
DataSourceService dataSourceService = new DataSourceService();
dataSourceService.init(url, userName, pwd);
//dataSourceService.initData(692396,100000);
dataSourceService.selectData("select * from device", new ProcessCallback() {
public void doAction(ResultSet rs) {
try {
while(rs.next()) {
System.out.println(rs.getString("device_id"));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}