gpt4 book ai didi

java - 如何将sql查询追加到java中的现有文件中?

转载 作者:行者123 更新时间:2023-12-02 09:46:40 24 4
gpt4 key购买 nike

我目前正在编写 Java 代码,它允许我查询数据库并将其内容提取到文件中。

到目前为止,小请求没有问题。

但是我很快就必须提取大量数据,几天来我一直在尝试实现最有效的解决方案,以尽可能限制内存消耗。

因为我一发出重要的请求,源机和目标机的内存就饱和了。

我在redhat linux环境上使用的java版本是java-1.8.0

到目前为止,我已经能够将查询结果重定向到文件。但经过大量文档后,我发现有很多不同的方法来限制内存消耗。

DriverManager.registerDriver(new              
com.wily.introscope.jdbc.IntroscopeDriver());
Connection conn = DriverManager.getConnection("jdbc:introscope:net//" +
user + ":" + password + "@" + hostname + ":" + port);

String query = "select * from metric_data"
+ " where agent='"
+ agents_filter
+ "' and metric='"
+ metrics_filter
+ "' and timestamp between "
+ queryInterval;

Statement ps=conn.createStatement();
ResultSet rs=ps.executeQuery(query);

rs.setFetchSize(Size);
ResultSetMetaData rsm = rs.getMetaData();
File output = new File("result");
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(output), "UTF-8")), false);

for(int i = 1; i <= rs.getMetaData().getColumnCount(); i++){
String colName = rs.getMetaData().getColumnName(i);
out.print(" " + colName + "\t\t" + "|");
}

while (rs.next()) {
for(int i = 1; i <= rs.getMetaData().getColumnCount(); i++){
String colValue = rs.getString(i);
out.print(" " + colValue + "\t" + "|");
}

out.println();
}


out.close();
out.flush();
rs.close();
ps.close();
conn.close();

当前请求已完全加载到内存中,然后重定向到我的文件。但一旦请求太重要,我就会收到以下消息:

线程“PO:client_main Mailman 2”中出现异常 java.lang.OutOfMemoryError: Java 堆空间线程“UnknownHub Hub 接收 1”中出现异常 java.lang.lang.OutOfMemoryError:Java 堆空间

我希望能够在文件中写入例如 1000 行 x 1000 行,以免内存饱和。

知道文件有时可以达到 40GB

执行时间并不是真正的问题,但内存消耗是一个非常重要的标准。

我距离 Java 专业人士还很远,所以我需要你的帮助。

预先感谢您的宝贵时间

最佳答案

  1. 通过连接字符串构建 SQL 字符串是一个安全漏洞。想象一下这些变量包含如下内容:“1'; DROP ALL TABLES; --”。即使在这里您知道字符串是“安全的”,代码发生变化,您也不应该养成坏习惯。解决这个问题;您可以使用PreparedStatement来修复它。

  2. 元数据不是免费的。缓存那些东西。具体来说,缓存值 rs.getMetaData().getColumnCount()

  3. 为了获得真正的速度,请运行一个 SQL 命令,告诉数据库引擎直接将该数据泵入文件,然后传输该文件(如果该文件不在本地主机上)。真的没有比这更快的了。

  4. 关闭后无法刷新,关闭意味着刷新。您只需删除flush()行即可。

  5. 假设您的提取大小不是大得离谱,则此代码中没有任何内容表明会发生内存不足错误。因此,要么是重复调用 getMetaData(这意味着缓存列大小可以解决您的问题),要么是数据库引擎和/或其 JDBC 驱动程序编写得不好。我没有听说过内窥镜,这就是我提到它的原因。如果是这种情况,您最多可以使用 SQL OFFSETLIMIT 将查询分成“页面”,这样就不会一次获取太多结果,但又不会ORDER 在你的 SQL 中,从技术上讲,数据库引擎可以改变你的顺序,这样,这个过程可能会变得相当慢。

关于java - 如何将sql查询追加到java中的现有文件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56595947/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com