【问题标题】:Criteria API ignores JOIN标准 API 忽略 JOIN
【发布时间】:2014-02-02 17:25:13
【问题描述】:

我有一个带有(内部)连接的简单标准 api 查询

public void find(Category category) {
 CriteriaBuilder b = getQueryBuilder();
 CriteriaQuery<Product> q = createQuery();
 Root<Product> root = q.from(Product.class);
 Join<Product, Category> myCategory= root.join("category");        
 q.where(b.equal(myCategory, category));
 entityManager.createQuery(q).getResultList();
}

查询有效,但如果我在 persistence.xml 中启用 sql 日志记录,我可以看到查询是一个

SELECT * FROM product, category WHERE ...

没有

SELECT * FROM product join category on category.id = product.category ...

知道这是什么原因吗? where 语句非常慢,所以真正的连接会更好。

我正在使用 eclipselink 2.5.1、Java EE7 和 postgres

我还有一个 Product 的超类

@Entity
@Audit
public class SuperClass {}

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Product extends SuperClass {}

但这应该没问题吧?

【问题讨论】:

    标签: java sql jpa eclipselink inner-join


    【解决方案1】:

    实际上正在执行连接,但是用于执行连接的 SQL 是用隐式连接表示法编写的。连接将具有与显式连接表示法(使用 JOIN 和 ON 的表示法)相同的性能。正在执行“真正的”连接,但它不是您所期望的显式连接表示法(也称为 ANSI SQL 92)。

    【讨论】:

    • 我不确定,你说“join on”的语法和“where”一样吗?有很大的性能差异。哪里的一切都将一切与一切进行比较,这使它变慢。我可以用数据库的回答时间来说这句话在哪里很慢,“加入”它很快
    • @user3263327 你不确定什么?
    • 好的,所以你是对的,en.wikipedia.org/wiki/Join_(SQL)#Inner_join 我必须阅读更多关于连接的内容。我想我必须更改联接类型(不再有内部联接)
    【解决方案2】:

    您正在从RootProduct.class 中进行选择,但您需要从加入中进行选择。 而且我认为你加入的结果必须映射到某个类,包含实体ProductCategory。如果你只想从 join 中获取产品,你可以这样写:

    CriteriaBuilder b = getQueryBuilder();
    CriteriaQuery<Product> q1 = createQuery();
    CriteriaQuery<Product> q2 = createQuery();
    Root<Product> root = q1.from(Product.class);        
    q2.select(root.as(Product.class)).from(root.join("category"))
    entityManager.createQuery(q2).getResultList();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多