java - 从具有 3000000 行的表的 Java 中读取行
问题描述
我想读取具有 30000000 行的表的行。我曾经st.setFetchSize(10000)
以为我会在 10000 个包中获得 30000000 行,但我只获得前 10000 行并且程序结束。请谁能告诉我如何在 10000 个包装中获得所有 30000000 行?
public class InsertBatch {
public static void main(String[] args) throws SQLException {
try (Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres", "postgres", "root")) {
connection.setAutoCommit(false);
Statement st = connection.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY,
ResultSet.FETCH_FORWARD
);
System.out.println(new Date());
st.setFetchSize(10000);
System.out.println("start query ");
ResultSet rs = st.executeQuery("SELECT * FROM contratacion");
System.out.println("done query ");
String insert = "INSERT INTO contrato(contrato, codigo_postal,cups) VALUES(?, ?, ?)\n" +
"ON CONFLICT (contrato) DO\n" +
"UPDATE SET codigo_postal = excluded.codigo_postal, cups = excluded.cups";
PreparedStatement pst = connection.prepareStatement(insert);
int cont = 0;
while(rs.next()) {
cont++;
Integer contrato = rs.getInt(1);
Integer codigo_postal = rs.getInt(2);
String cups = rs.getString(3);
pst.setInt(1, contrato);
pst.setInt(2, codigo_postal);
pst.setString(3, cups);
pst.executeUpdate();
connection.commit();
System.out.println(cont);
}
System.out.println(new Date());
} catch (SQLException ex) {
}
}
}
解决方案
请阅读文档,即 javadoc createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
:
参数:
resultSetType
- 以下ResultSet
常数之一:ResultSet.TYPE_FORWARD_ONLY
,ResultSet.TYPE_SCROLL_INSENSITIVE
, 或ResultSet.TYPE_SCROLL_SENSITIVE
resultSetConcurrency
- 以下ResultSet
常数之一:ResultSet.CONCUR_READ_ONLY
或ResultSet.CONCUR_UPDATABLE
resultSetHoldability
- 以下ResultSet
常数之一:ResultSet.HOLD_CURSORS_OVER_COMMIT
或ResultSet.CLOSE_CURSORS_AT_COMMIT
你的代码是:
Statement st = connection.createStatement(
ResultSet.TYPE_FORWARD_ONLY, // Good
ResultSet.CONCUR_READ_ONLY, // Good
ResultSet.FETCH_FORWARD // BAD !!!!!
);
如您所见,第三个参数不是有效值之一。
由于您connection.commit();
在while(rs.next())
循环内调用,因此如果您通过ResultSet.HOLD_CURSORS_OVER_COMMIT
.
当然,您甚至不应该这样做,因为 3000000 条INSERT
语句将永远持续下去,特别是如果您单独提交每条语句。哎呀!
如果必须,因为需要在 Java 中处理数据,至少使用批处理。
相反,只需将其编写为单个语句:
INSERT INTO contrato ( contrato, codigo_postal, cups )
SELECT contrato, codigo_postal, cups
FROM contratacion
ON CONFLICT (contrato) DO UPDATE
SET codigo_postal = excluded.codigo_postal
, cups = excluded.cups
推荐阅读
- amazon-web-services - 如何确认对 aws SNS 主题的松弛订阅?
- node.js - 当我需要时,如何在我自己的服务器上托管 gatsby 并构建网站
- xamarin - MasterDetailPage - 找不到任何方法来定位“详细”页面窗口
- html - 如何发送坐标纬度,日志以打开本地谷歌地图应用程序并制作路由器
- azure-cosmosdb - 如何使用 azure 流分析将 cosmosdb 中的值更新为输出?
- docker - manage.py 没有这样的文件或目录
- npx - 如何使用 npx 使私有 npm repo 可执行?
- javascript - 如何获取单击记录的动态循环元素的 ID
- angular - 如何在 scss 文件中导入 scss 文件?
- python - python check_output FileNotFoundError: [WinError 2] 系统找不到指定的文件