我有一個程序逐行讀取文本文件,並從每行創建一個Hibernate實體對象,並將它們保存。我有幾個這樣的文本文件要處理,每個文件都有大約30萬行。我發現我目前的執行速度非常慢,而且我想知道是否有任何事情可以改進。快速批量保存Hibernate的方法?
我的主要方法,通過線處理文本文件行,像這樣:
// read the file line by line
FileInputStream fileInputStream = new FileInputStream(new File(fileName));
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
int lineCount = 0;
String line = bufferedReader.readLine();
while (line != null)
{
// convert the line into an Observations object and persist it
convertAndPersistObservationsLine(line);
// if the number of lines we've processed has built up to the JDBC batch size then flush
// and clear the session in order to control the size of Hibernate's first level cache
lineCount++;
if (lineCount % JDBC_CACHE_SIZE == 0)
{
observationsDao.flush();
observationsDao.clear();
}
line = bufferedReader.readLine();
}
的convertAndPersistObservationsLine()方法只是拆分文本行成標記,創建一個新的實體對象,從數據填充實體的領域令牌,然後通過調用Hibernate的Session.saveOrUpdate()方法的DAO保存對象。 DAO方法flush()和clear()是直接調用相應的Hibernate Session方法。
Hibernate屬性'hibernate.use_second_level_cache'設置爲false,並且Hibernate屬性'hibernate.jdbc.batch_size'設置爲50,Java常量JDBC_CACHE_SIZE也是如此。
有人可以提出一個更好的方法來解決這個問題,或者對上面的任何調整都可以提高這個批量加載程序的性能嗎?
在此先感謝您的幫助。
- 詹姆斯
你有正確設置交易,沒有自動提交等?你的dao不會意外刷新會話持續嗎?你能分析代碼,看看大部分時間都花在哪裏嗎?你能否啓用sql日誌來驗證沒有中間刷新? – 2010-08-12 16:31:50
是否最好將Hibernate屬性'hibernate.connection.autocommit'設置爲false(默認情況下該值爲true)?我的DAO不會調用flush(),只會在返回前調用saveOrUpdate()。我還沒有分析代碼,也沒有監視中間沖洗的日誌,感謝這些建議。 – 2010-08-12 16:47:19
亞當我建議看一下由hibernate和spring生成的日誌,以查看插入過程中發生了什麼;我認爲無論是Spring還是Hibernate都會在事務中禁用自動提交(使設置無關緊要,但您應該確認)。 – 2010-08-12 18:10:36