Java 根据ram大小、行数和列数限制结果集并写入文件

Java 根据ram大小、行数和列数限制结果集并写入文件,java,mysql,jdbc,Java,Mysql,Jdbc,我正在用Java开发一个系统,它读取所有MySQL数据库表,执行一些操作,最后将所有数据写入一个文件(每个表有单独的文件) 由于所有的数据库表都有不同的列数和行数,如果数据高于我们的系统所能处理的,则可能会出现内存问题。因此,我需要编写代码,逐块读取表值并将数据写入文件;在迭代之后,所有的数据都被写入该文件 我相信这种方法可以在任何RAM大小的系统中运行,这样系统就不会出现内存问题。目前,对于任何表,我都会限制查询结果并将结果写入一个文件中,并反复迭代此过程,直到所有结果都未被处理。这里,所有表

我正在用Java开发一个系统,它读取所有MySQL数据库表,执行一些操作,最后将所有数据写入一个文件(每个表有单独的文件)

由于所有的数据库表都有不同的列数和行数,如果数据高于我们的系统所能处理的,则可能会出现内存问题。因此,我需要编写代码,逐块读取表值并将数据写入文件;在迭代之后,所有的数据都被写入该文件

我相信这种方法可以在任何RAM大小的系统中运行,这样系统就不会出现内存问题。目前,对于任何表,我都会限制查询结果并将结果写入一个文件中,并反复迭代此过程,直到所有结果都未被处理。这里,所有表的限制大小和迭代次数的值都是动态的,即取决于行数、列数和RAM大小

下面是到目前为止编写的代码

public static void main(String[] args) throws Exception {

    List<String> dbList = MySqlUtils.getAllTableNames("datahouse");

    for (String tableName : dbList) {
        processTable(tableName);
    }
}

public static void processTable(String tableName) throws Exception {
    String dbname = "datahouse";
    int startIndex = 0;
    int limit = getMySqlQueryLimit(dbname, tableName);
    int endIndex = limit;
    int iteratorLength = getIteratorLength(dbname, tableName);

    for (int i = 1; i <= iteratorLength; i++) {

        ResultSet resultSet = getResultSet(tableName, startIndex, endIndex);

        while (resultSet.next()) {
            // Write into file after some operation
        }
        startIndex = endIndex;
        endIndex += limit;
    }
}

public static ResultSet getResultSet(String tableName, int startLimit, int endLimit) throws SQLException {

    StringBuilder builder = new StringBuilder();
    builder.append("SELECT * FROM " + tableName);
    builder.append("ORDER BY id ASC limit (");
    builder.append(startLimit);
    builder.append(",");
    builder.append(endLimit);
    builder.append(")");

    return MySqlUtils.getStatement().executeQuery(builder.toString());
}

public static int getMySqlQueryLimit(String dbName, String tableName) throws SQLException {

    long ramSize = SystemUtils.getPhysicalMemorySize();
    int columnSize = getColumnCount(dbName, tableName);
    int totalRows = getRowsCount(dbName, tableName);

    //TODO

    return 0;
}

public static int getIteratorLength(String dbName, String tableName) {

    try {
        long ramSize = SystemUtils.getPhysicalMemorySize();
        int columnSize = getColumnCount(dbName, tableName);
        int totalRows = getRowsCount(dbName, tableName);

        //TODO

        return 0;
    } catch (SQLException e) {
        e.printStackTrace();
        return 0;
    }
}
publicstaticvoidmain(字符串[]args)引发异常{
List dbList=MySqlUtils.getAllTableNames(“数据库”);
for(字符串表名:dbList){
processTable(表名);
}
}
公共静态void processTable(字符串tableName)引发异常{
字符串dbname=“datahouse”;
int startIndex=0;
int limit=getMySqlQueryLimit(dbname,tableName);
int ENDIX=极限;
int iteratorLength=getIteratorLength(dbname,tableName);

对于(int i=1;i为什么不直接使用
setFetchSize
?是什么让你认为
ResultSet
完全加载在内存中?请阅读这里:@petermm实际上,默认情况下,MySQL是这样。请参阅中的ResultSet部分。@Sushil,也阅读它,因为这是解决问题的一个更简单的解决方案。听起来你正试图这样做“重新发明轮子”。MySQL Connector/J已经有了一个功能,可以通过使用前向只读结果集和使用
setFetchSize(Integer.MIN_VALUE)
来“流式”查询结果。有关详细信息,请参阅和。