我有以下hibernate查询:
Query query = session.createQuery("from MyHibernateClass");
List<MyHibernateClass> result = query.list();// executes in 7000ms
Run Code Online (Sandbox Code Playgroud)
当我在MySQL中记录正在执行的sql时,我看到了
select
myhibernat0_.myFirstColumn as myfirstcolumn92_,
myhibernat0_.mySecondColumn as mysecondcolumn92_,
myhibernat0_.mythirdcolumn as mythirdcolumn92_,
myhibernat0_.myFourthColumn as myfourthcolumn92_
from MyHibernateClass myhibernat0_
where (1=1);
Run Code Online (Sandbox Code Playgroud)
当在MyHibernateClass数据库表中的3500行的小数据集上测量jvm中的java代码时,这需要大约7000ms.
如果我在另一方面使用直接jdbc如下:
Statement statement = session.connection().createStatement();
ResultSet rs = statement.executeQuery("select * from MyHibernateClass");// 7ms
List<MyHibernateClass> result = convert(rs);// executes in 20ms
Run Code Online (Sandbox Code Playgroud)
我看到相同的sql进入数据库,但现在jvm中java代码的花费时间是7ms.
MyHibernateClass是一个带有getter和setter的简单java bean类,我没有使用特殊的resulttransformers,如示例中所示.我只需要该类的只读实例,并且不需要附加到hibernate会话.
我宁愿使用hibernate版本但不能接受执行时间.
补充信息:添加hibernate日志后我看到了
[2011-07-07 14:26:26,643]DEBUG [main] [logid: ] -
org.hibernate.jdbc.AbstractBatcher.logOpenResults(AbstractBatcher.java:426) -
about to open ResultSet (open ResultSets: 0, globally: 0)
Run Code Online (Sandbox Code Playgroud)
接下来是3500条以下日志语句
[2011-07-07 14:26:26,649]DEBUG [main] …Run Code Online (Sandbox Code Playgroud) 我刚刚在探查器下测试了我的应用程序,发现sql字符串占用了大约30%的内存!这很奇怪.
应用程序内存中存储了很多像这样的字符串.这是由hibernate生成的SQL查询,请注意不同的数字和尾随下划线:
select avatardata0_.Id as Id4305_0_,...... where avatardata0_.Id=? for update
select avatardata0_.Id as Id4347_0_,...... where avatardata0_.Id=? for update
Run Code Online (Sandbox Code Playgroud)
这是我无法理解的部分.为什么hibernate必须为每个查询生成具有不同标识符的不同sql字符串,如" Id4305_0_ "?为什么不能为所有相同的查询使用一个查询字符串?这是绕过查询缓存的某种技巧吗?
如果有人能形容我为什么会这样,以及如何避免这种资源浪费,我将不胜感激.
UPDATE
好.我找到了.假设内存泄漏我错了,这是我的错.Hibernate按预期工作.
我的应用程序在10个线程中创建了121(!)SessionFactories,它们生成了大约2300个SingleTableEntityPersisters实例.每个SingleTableEntityPersister生成大约15个具有不同标识符的SQL查询.Hibernate被迫生成大约345,000个不同的SQL查询.一切都很好,没什么奇怪的:)