HQL查询是否总是会访问数据库并获取结果?

6
我正在学习Hibernate,想了解何时应使用CriteriaHQL查询。我的理解是,在Hibernate中,无论是通过Criteria还是HQL查询数据库,Hibernate都会将结果集放入内存中,当我们再次调用该查询时,数据将从内存中获取而非重新查询数据库。请问我理解正确吗?
另外,正如下面问题的评论所提到的,有人建议使用Hibernate Criteria从session中获取数据,而HQL则总是会直接查询数据库。如果这是事实,那么多次调用HQL查询将导致频繁查询数据库,而引发更多问题。请您指点迷津。
参考:问题
2个回答

7

1
据我所知,HQL查询仅使用查询缓存,并且仅在查询及其所有参数相同时从缓存中获取结果。 - Thomas
@Juha:所以现在你说会话默认总是开启,那么 HQL 应该从会话中获取结果,而不是再次访问数据库,对吧? - Rachel
@Rachel,请看下面我的回答。会话缓存始终处于开启状态,但查询永远不会进入会话缓存。执行查询将触发刷新和数据库访问。它可能会命中查询缓存,但这是另一回事。 - Alex Barnes
@Alex:好的,但我该如何确保查询仅从内存中获取结果集,而不是从数据库中获取呢?我想在这里减少数据库访问次数,因为它会严重影响性能。有什么想法吗? - Rachel
1
@JuhaSyrjälä:为什么我需要同时激活查询缓存和第二级缓存来防止数据库访问,难道查询缓存不能防止数据库访问吗?有没有任何特定的参考资料可以帮助我理解这个问题? - Rachel
显示剩余3条评论

2

基本上,如果您要生成查询,则可能会访问数据库,除非您已缓存查询和参数。

Hibernate查询(无论您使用标准或HQL)只会在使用@Id获取实体时从会话缓存(一级缓存)返回。

为了缓存查询,您可以使用以下语法:

session.createQuery("from X as x").setCacheable(true);

编辑评论:

查询不同于使用@Id进行获取。要通过@Id获取对象,您需要编写类似以下的代码:

Entity myEntity = sessionFactory.getCurrentSession().get(Entity.class, 1);

你能给出一个使用 @Id 获取 Hibernate 查询的例子吗? - Rachel
类似这样的代码使用 HQL 通过主键 (@Id) 进行查询:session.createQuery("from Entity e where e.id = ? ").setParameter(1, id) - Juha Syrjälä
这不会命中会话缓存。你正在创建一个查询,将绕过会话缓存直接访问数据库。如果你想通过 @Id 获取,请在会话上使用 Load 或 Get。 - Alex Barnes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接