读取一个固定长度的基于位置的文件,并在Java中插入到oracle表中
目前,我正在研究一种通过Java读取454个字符/行的大型文件(至少50000行)的解决方案。根据要求,它是一个基于位置的文件,我们首先需要读取该文件,然后解析基于位置的值,并需要插入到表中。(表格的96列中至少插入96个位置) 我在解析之后接受了这个概念读取一个固定长度的基于位置的文件,并在Java中插入到oracle表中,java,sql,rest,file,jakarta-ee,Java,Sql,Rest,File,Jakarta Ee,目前,我正在研究一种通过Java读取454个字符/行的大型文件(至少50000行)的解决方案。根据要求,它是一个基于位置的文件,我们首先需要读取该文件,然后解析基于位置的值,并需要插入到表中。(表格的96列中至少插入96个位置) 我在解析之后接受了这个概念 [ INSERT ALL INTO<TABLE NAME> [COL1,COL2,COL3] Values [VAL1,VAL2,VAL3] INTO<TABLE NAME> [COL1
[ INSERT ALL INTO<TABLE NAME> [COL1,COL2,COL3] Values [VAL1,VAL2,VAL3]
INTO<TABLE NAME> [COL1,COL2,COL3] Values [VAL1,VAL2,VAL3]
SELECT * FROM DUAL;]
但一旦我运行了代码,如果有40-50行代码,它就可以正常工作了。但不仅仅如此,我还遇到了异常。有人能和我分享运行代码的正确方法吗,这样我就可以使用它了。
首先,请不要使用字符串连接来构建包含外部文本值的SQL语句。它使您容易受到攻击,并可能导致SQL语法错误。改用带有
?
参数标记的
其次,如果要插入大量记录,请使用JDBC批处理
以下是您将如何使用它的示例:
String sql = "INSERT INTO MyTable" +
" ( Col1, Col2, Col3, Col4, Col5, Col6, Col7 )" +
" VALUES (?,?,SYSDATE,?,?,?,?)";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
char[] line = new char[456];
int batchSize = 0;
while (br.read(line) > 0) {
String input = new String(line);
int detailFileId = interfaceFileSequence();
stmt.setInt (1, detailFileId);
stmt.setInt (2, interfaceHeaderId);
stmt.setInt (3, interfaceRunId);
stmt.setString(4, toString(input.substring(0, 2)));
stmt.setDate (5, toDate(input.substring(2, 12)));
stmt.setString(6, toString(input.substring(12, 22)));
// ...
stmt.addBatch();
if (++batchSize == 1000) {
stmt.executeBatch();
batchSize = 0;
}
}
if (batchSize != 0) {
stmt.executeBatch();
}
} catch (IOException e) {
e.printStackTrace();
}
上述代码使用以下帮助器方法保留代码:
有什么例外?发布堆栈跟踪。出现超时异常。此外,我们正在从REST-WS调用此函数。可能需要将代码移动到异步任务,以便REST调用可以立即返回,其中初始调用将返回一个“started”响应。然后提供另一个REST端点,客户端可以在其中偶尔调用以获取状态/进度。是。这是个好建议。但在这个加载之后,我们需要基于加载结果的其他进程,以及客户端如何获得加载是否完成的信息。此外,还有更好的解析和插入方法。状态端点返回当前进度,例如属性status为“working”、“completed”和“error”的JSON,以及可由客户端显示的processedCount。加载任务的结束可能会触发另一个异步任务,或者将任务安排在将来某个时间运行。另一部分是应该发布的代码审查。我同意这些建议,只是我会使用
stmt.setObject()
设置一个现代的LocalDate
,而不是老式的java.sql.Date
。这也将在toDate()
中为您保存一个转换。
String sql = "INSERT INTO MyTable" +
" ( Col1, Col2, Col3, Col4, Col5, Col6, Col7 )" +
" VALUES (?,?,SYSDATE,?,?,?,?)";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
char[] line = new char[456];
int batchSize = 0;
while (br.read(line) > 0) {
String input = new String(line);
int detailFileId = interfaceFileSequence();
stmt.setInt (1, detailFileId);
stmt.setInt (2, interfaceHeaderId);
stmt.setInt (3, interfaceRunId);
stmt.setString(4, toString(input.substring(0, 2)));
stmt.setDate (5, toDate(input.substring(2, 12)));
stmt.setString(6, toString(input.substring(12, 22)));
// ...
stmt.addBatch();
if (++batchSize == 1000) {
stmt.executeBatch();
batchSize = 0;
}
}
if (batchSize != 0) {
stmt.executeBatch();
}
} catch (IOException e) {
e.printStackTrace();
}
private static String toString(String text) {
String trimmed = text.trim();
return (trimmed.isEmpty() ? null : trimmed);
}
private static java.sql.Date toDate(String text) {
String trimmed = text.trim();
return (trimmed.isEmpty() ? null : java.sql.Date.valueOf(LocalDate.parse(trimmed)));
}