我有一个程序逐行读取文本文件,并从每行创建一个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