我目前正在编写一个Java程序,它循环遍历大约4000个XML文件的文件夹。
使用for循环,它从每个文件中提取XML,将其分配给String'xmlContent',并使用PreparedStatement方法setString(2,xmlContent)将String插入存储在SQL Server中的表中。
列'2'是一个名为'Data'的XML类型的列。
这个过程有效,但速度很慢。它每隔7秒就会在表格中插入大约50行。
有没有人对如何加快这个过程有任何想法?
代码:
{ ...declaration, connection etc etc
PreparedStatement ps = con.prepareStatement("INSERT INTO Table(ID,Data) VALUES(?,?)");
for (File current : folder.listFiles()){
if (current.isFile()){
xmlContent = fileRead(current.getAbsoluteFile());
ps.setString(1, current.getAbsoluteFile());
ps.setString(2, xmlContent);
ps.addBatch();
if (++count % batchSize == 0){
ps.executeBatch();
}
}
}
ps.executeBatch(); // performs insertion of leftover rows
ps.close();
}
private static String fileRead(File file){
StringBuilder xmlContent = new StringBuilder();
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String strLine = "";
br.readLine(); //removes encoding line, don't need it and causes problems
while ( (strLine = br.readLine() ) != null){
xmlContent.append(strLine);
}
fr.close();
return xmlContent.toString();
}
答案 0 :(得分:2)
只需通过一点阅读和快速测试 - 看起来您可以通过关闭连接上的autoCommit来获得不错的加速。我看到的所有批处理查询教程也推荐它。例如http://www.tutorialspoint.com/jdbc/jdbc-batch-processing.htm
将其关闭 - 然后在您想要的位置删除显式提交(在每个批处理结束时,在整个函数结束时等)。
conn.setAutoCommit(false);
PreparedStatement ps = // ... rest of your code
// inside your for loop
if (++count % batchSize == 0)
{
try {
ps.executeBatch();
conn.commit();
}
catch (SQLException e)
{
// .. whatever you want to do
conn.rollback();
}
}
答案 1 :(得分:0)
最好使读写并行。
使用一个线程读取文件并存储在缓冲区中。 使用另一个线程从缓冲区读取并在数据库上执行查询。
您可以使用多个线程并行写入数据库。这应该会给你更好的表现。
我建议您遵循这种MemoryStreamMultiplexer方法,您可以在一个线程中读取XML文件并存储在缓冲区中,然后使用一个或多个线程从缓冲区读取并针对数据库执行。
http://www.codeproject.com/Articles/345105/Memory-Stream-Multiplexer-write-and-read-from-many
这是一个C#实现,但你明白了。