Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用java将大量数据从数据库导出到.csv时出现问题_Java_Database_Memory_Export To Csv - Fatal编程技术网

使用java将大量数据从数据库导出到.csv时出现问题

使用java将大量数据从数据库导出到.csv时出现问题,java,database,memory,export-to-csv,Java,Database,Memory,Export To Csv,一、 谢谢你的关注 我想使用java将大量数据(600万行)导出到.csv文件中。该应用程序是一个swing应用程序,带有JPA,使用toplink(ojdbc14) 我尝试使用: 缓冲写入程序 随机存取文件 文件通道 等等,但内存消耗仍然很高,导致Java堆内存不足异常,尽管我将最大堆大小设置为800m(-Xmx800m) 我最新版本的源代码: ...(more lines of code) FileChannel channel = getRandomAccessFile(tempFile

一、 谢谢你的关注

我想使用java将大量数据(600万行)导出到.csv文件中。该应用程序是一个swing应用程序,带有JPA,使用toplink(ojdbc14)

我尝试使用:

缓冲写入程序 随机存取文件 文件通道

等等,但内存消耗仍然很高,导致Java堆内存不足异常,尽管我将最大堆大小设置为800m(-Xmx800m)

我最新版本的源代码:

...(more lines of code)

FileChannel channel = getRandomAccessFile(tempFile).getChannel();
Object[][] data = pag.getRawData(); //Database data in a multidimentional array

            for (int j = 0; j < data.length; j++) {
                write(data[j], channel); //write data[j] (an array) into the channel
                freeStringLine(data[j]); //data[j] is an array, this method sets all positions =null
                data[j] = null;//sets reference in null
            }

            channel.force(false); //force writing in file system (HD)
            channel.close(); //Close the channel
            pag = null; 

...(more lines of code)

 private void write(Object[] row, FileChannel channel) throws DatabaseException {
    if (byteBuff == null) {
        byteBuff = ByteBuffer.allocateDirect(1024 * 1024);
    }
    for (int j = 0; j < row.length; j++) {
        if (j < row.length - 1) {
            if (row[j] != null) {
                byteBuff.put(row[j].toString().getBytes());
            }
            byteBuff.put(SPLITER_BYTES);
        } else {
            if (row[j] != null) {
                byteBuff.put(row[j].toString().getBytes());
            }
        }
    }
    byteBuff.put("\n".toString().getBytes());        
    byteBuff.flip();
    try {
        channel.write(byteBuff);
    } catch (IOException ex) {
        throw new DatabaseException("Imposible escribir en archivo temporal de exportación : " + ex.getMessage(), ex.getCause());
    }
    byteBuff.clear();
}
…(更多行代码)
FileChannel channel=getRandomAccessFile(tempFile).getChannel();
对象[][]数据=pag.getRawData()//多维数组中的数据库数据
对于(int j=0;j
由于有600万行,我不想在创建文件时将这些数据存储在内存中。我制作了许多临时文件(每个文件有5000行),在这个过程的最后,使用两个FileChannel将所有这些临时文件附加到一个文件中。但是,内存不足的例外情况是在加入之前启动的

您现在是否有导出大量数据的另一种策略

非常感谢您的回复。对不起,我的英语水平提高了xD

答案是使用“流”方法-即在数据集中滚动时读一行,写一行。您需要以游标的形式获取查询结果并对其进行迭代,而不是获取整个结果集

在JPA中,使用如下代码:

ScrollableResults cursor = session.createQuery("from SomeEntity x").scroll();

while (cursor.next()) {
    writeToFile(cursor);
}
这意味着您一次只有一行内存,这完全可以扩展到任意数量的行,并且使用最少的内存(无论如何速度更快)


一次获取结果集中的所有行是一种方便的方法,适用于较小的结果集(大多数情况下都是如此),但通常来说,方便是有代价的,而且并非在所有情况下都有效。

最好将数据库中的数据作为页面加载,并将每个页面写入文件,然后在加载下一页之前丢弃该页。是否分析了应用程序以查看对象/类之间的内存使用情况?我怀疑这是由于持久性上下文的大小。另外,如果你能写到CSV文件的末尾,那么加入文件也不值得。感谢Jeremy和Vinet的回复。Jeremy,我创建了很多档案,因为我在最早版本的源代码中使用了BufferedWriter。但我将尝试使用一个带有FileChannel:)的文件。在Vinet中,我使用NetBeans 6.9的分析器来分析内存消耗。遗憾的是,“live results”选项卡显示内存消耗最多的类是字节数组(byte[]),也许我并不完全了解分析器。关于持久性上下文,禁用缓存可以减少内存消耗?哦,非常感谢您的回复。尽管如此,我并没有使用te createQuery()方法(我认为会话是查询类的一个实例),而是使用te createNativeQuery()方法,它执行一个复杂的查询(连接3个表)。你的方法对我的问题正确吗?(我在查询:S中没有使用实体名称)@Bohemian需要您的帮助……我正在使用hibernate,面临同样的问题。表中有200万条记录。我想将表中的所有200万条记录写入csv文件。通过上述解决方案。。。。它将引发大约200万次的查询…只是想知道它是否是这样做的正确和唯一方法。或者我们可以创建多个线程,并允许它们从表中读取以提高速度。。但问题还是出现了,比如我们如何保持某一特定记录已经通过线程读出。请帮忙。。在过去的三周里,这个问题还没有答案。@sparsh610我认为一个运营需求应该有一个运营解决方案。Java非常适合处理单个请求的应用程序。它不适合处理批量操作。我强烈建议不要为此使用java。使用shell命令调用数据库实用性函数。每个数据库都有一种将数据转储到csv的简单方法—使用它。它将是简单易懂的代码,可靠且比java中的任何操作都要快。@Bohemian非常感谢。。。我急切地期待着你的答复。。。你的回答是…在最坏的情况下,如果我们必须通过Java来实现,那么什么是最好的最快实现方法。请帮助我:)我也尝试过谷歌搜索,但没有找到太多相同的方法