【问题标题】:Does HQL query always hit database and get results?HQL 查询是否总是命中数据库并获得结果?
【发布时间】:2012-02-17 20:41:26
【问题描述】:

我正在经历休眠以及何时使用Criteria vs HQL 的情况,我的理解是,对于休眠,每次我们通过CriteriaHQL 查询数据库时,在这两种情况下休眠都会得到结果集并放入内存,然后当我们再次调用该查询时,将从内存中获取数据而不是访问该数据库,我的理解是否正确?

您还可以从 cmets 看到下面提到的问题,建议 Hibernate Criteria 将从会话中获取数据,而 HQL 总是会访问数据库,因此对 HQL 查询的任意数量的多次调用都会访问数据库和如果是这种情况,那么HQL 会导致比解决更多的问题。

由于我对这种情况有点困惑,请就此提出建议。

参考question

【问题讨论】:

    标签: java hibernate orm hql criteria


    【解决方案1】:

    基本上,如果您正在生成查询,您可能会访问数据库,但如果您缓存了查询和参数,则例外。

    Hibernate 查询(无论您使用 Criteria 还是 HQL)只有在您使用 @Id 获取时才会从会话缓存(一级缓存)返回实体。

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

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

    为 cmets 编辑:

    查询与使用@Id 的获取不同。要通过 @Id 获取对象,您可以编写如下内容:

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

    【讨论】:

    • 你能举一个使用@Id获取它的休眠查询示例
    • 这样的事情使用 HQL 来获取主键 (@Id) session.createQuery("from Entity e where e.id = ? ").setParameter(1, id)
    • 这不会命中会话缓存。您正在创建一个将绕过会话缓存并直接进入数据库的查询。如果您想通过 @Id 获取,请在会话中使用 Load 或 Get。
    【解决方案2】:

    这取决于您进行的查询类型以及缓存设置。

    Hibernate 有三种缓存:会话缓存、查询缓存和二级缓存。会话缓存始终打开,但其他两个可以禁用。

    通常缓存不是支持 Criteria API 而不是 HQL 的原因,反之亦然。它们大多只是本质上相同事物的不同接口。

    http://www.javalobby.org/java/forums/t48846.htmlhttp://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html

    【讨论】:

    • AFAIK 一个 HQL 查询将只使用查询缓存,并且只有在查询和所有参数都相同时才从那里获取结果。
    • 所以如果我正在制作"from " + test.class.getName() + SORT_BY_ID;,我如何确定它是在访问内存还是数据库,我们如何在hibernate v3.2中管理缓存设置?
    • @Juha:所以现在当你说会话默认情况下总是打开时,HQL 应该从会话中获取结果,而不是再次访问数据库对吗?
    • @Rachel 在下面看到我的答案。会话缓存始终打开,但查询永远不会进入会话缓存。执行查询将触发刷新和数据库命中。它可能会命中查询缓存,但这是另一回事。
    • @JuhaSyrjälä:为什么我需要同时激活查询缓存和二级缓存以防止数据库访问,不会查询缓存防止数据库命中,是否有任何具体的参考我应该寻找这种理解?
    猜你喜欢
    • 1970-01-01
    • 2010-09-22
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多