这个问题可能已经回答了,但是我找不到一个很好的问题,我试图从一个数据库中读取数据并执行一些操作,而我的源数据库非常庞大,例如1亿条记录或100GB的表,所以我尝试使用下面的方法一次提取很少的记录,这样我就不会出现内存异常,但是得到的只是我设置为setMaxRows()的最大记录,例如,如果我设置为100,仅获得100,而我正在针对mysql数据库进行测试。
这是我的Java代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCTest {
public static void main(String[] args) throws SQLException {
Connection conn=null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "root", "root");
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
stmt.setMaxRows(100);
ResultSet rs = stmt.executeQuery("select * from mydatabase.posthistory");
int i=0;
for (;;) {
System.out.println("Reading the set from: "+i);
while (rs.next()) {
i++;
System.out.println(i);
}
if ((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1)) {
System.out.println("End of reading.");
break;
}
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
conn.close();
}
}
}
有人可以告诉我我在做什么错。任何帮助或建议都会很棒。我正在使用mysql jsbc驱动程序版本5.1.22。如果我正常运行它,那么Java会尝试将整个数据带入ram,这会引发错误,
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
答案 0 :(得分:0)
使用Statement.setFetchSize
来控制缓冲的行数。默认值为0,这可以缓冲整个结果,具体取决于驱动程序。
请注意,MySQL JDBC option useCursorFetch
应该启用,setFetchSize
才能正常工作。参见implementation notes:
另一种选择是使用基于游标的流来检索集合 每次的行数。可以通过设置连接来完成 将useCursorFetch属性设置为true,然后调用setFetchSize(int) int是每次要获取的所需行数:
conn = DriverManager.getConnection(
"jdbc:mysql://localhost/?useCursorFetch=true", "user", "s3cr3t"
);
stmt = conn.createStatement();
stmt.setFetchSize(100);
rs = stmt.executeQuery("SELECT * FROM your_table_here");
Statement.setMaxRows
仅限制返回的行数,并导致多余的行被丢弃,如您观察到的那样。
答案 1 :(得分:0)
特别用于Mysql数据库
stmt = connection.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
对于其他数据库
stmt.setFetchSize(1000);
这不会将整个数据库提取到ResultSet对象中。