【问题标题】:Hibernate: how to make EXISTS query? (not subquery)Hibernate:如何进行 EXISTS 查询? (不是子查询)
【发布时间】:2011-08-05 01:43:25
【问题描述】:

例如:

EXISTS ( SELECT * FROM [table] WHERE ... )

如何使用 Hibernate 进行这样的查询?

【问题讨论】:

    标签: hibernate hql


    【解决方案1】:

    另外,如果您使用JpaRepository,您可以通过 ORM 轻松检查实体是否存在。这是一个 Kotlin 示例:

    interface UserRepository : JpaRepository<User, Long> {
        fun existsByUsername(username: String): Boolean
    }
    

    【讨论】:

      【解决方案2】:

      HQL 不允许使用exists 语句。 UPD 从 Hibernate 5 开始 it supports it as a predicate in WHERE

      您可以使用多种方法:

      1. 对于 Hibrnate 5:您可以对同一表 boolean exists = session.createQuery("select 1 from PersistentEntity where exists (select 1 from PersistentEntity p where ...)").uniqueResult() != null; 使用子查询。感谢以下作者。
      2. count(*) &gt; 0 但这不利于性能Avoid Using COUNT() in SQL When You Could Use EXISTS()
      3. 使用boolean exists = session.createQuery("from PersistentEntity where ...").setMaxResults(1).uniqueResult() != null;,但这将强制 Hibernate 加载所有字段并对对象进行水合,即使您只需要检查空值。
      4. 使用session.get(PersistentEntity.class, id) != null,如果您启用二级缓存,这会更快,但如果您需要更多的条件而不是id,这将是一个问题。
      5. 您可以使用以下方法:getSession().createQuery("select 1 from PersistentEntity where ...").uniqueResult() != null)

      【讨论】:

      • 我今天投了反对票,因为“HQL 不允许使用存在”的说法不正确。 docs.jboss.org/hibernate/orm/5.1/userguide/html_single/…
      • 我不确定新更改是否完全准确。该问题专门要求“非子查询”,但exists 的新解决方案使用子查询。与其他解决方案相比,我还希望对新 exists 的性能发表评论。
      【解决方案3】:

      有一些关于使用 EXISTS 的不错的 cmets,但没有示例。这是我在 Hibernate 5.2 中的解决方案:

      boolean exists = session.createQuery( 
                          "SELECT 1 FROM PersistentEntity WHERE EXISTS (SELECT 1 FROM PersistentEntity p WHERE ...)")
                  .uniqueResult() != null;
      

      【讨论】:

        【解决方案4】:

        试试:

        "select count(e) > 0 from Entity e where..."
        

        适用于 Spring Data。

        【讨论】:

          【解决方案5】:

          我使用了以下内容:SELECT COUNT(e) FROM Entity e。在Spring Data JPA 中工作得非常好。

          【讨论】:

          • 我得到了一个java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Boolean 使用您对 Spring Data 的查询。你能展示一个完整的工作示例吗?
          【解决方案6】:

          如果我们使用WHERE子句,数据库可能需要扫描整个表来统计符合我们条件的记录,但我们可以限制只搜索一条记录,这足以说明空虚。

          如果没有任何搜索过滤器,则可以接受之前的查询,因为数据库会使用索引进行一些优化。

          所以我想下面的查询会比上一个查询提高一些性能:

          boolean exists = session.createQuery("from PersistentEntity where ...").setMaxResults(1).uniqueResult() != null;
          

          【讨论】:

            【解决方案7】:

            如果您的目标是检查一些空的集合,您可以使用简单的 HQL 查询:

            boolean exists = (Long) session.createQuery("select count(*) from PersistentEntity where ...").uniqueResult() > 0
            

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-11-30
            • 1970-01-01
            • 2018-03-30
            相关资源
            最近更新 更多