【问题标题】:Get all columns of two table joined with criteria Query in JPA获取两个表的所有列与 JPA 中的条件查询连接
【发布时间】:2016-04-08 09:30:22
【问题描述】:

我已经使用 Jpa Api 标准连接了两个表。但我需要加入两个表的列:

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
        CriteriaQuery<FacturePoste> criteria = criteriaBuilder.createQuery(FacturePoste.class);
        Root<FacturePoste> root = criteria.from(FacturePoste.class);
        Join<FacturePoste, FactureEntete> contactInfoJoin = root.join("numeroFacture");
          TypedQuery<FacturePoste> query = em.createQuery(criteria.multiselect(contactInfoJoin));list = query.getResultList();

请帮帮我。

【问题讨论】:

  • 所以不打算发布课程?或者告诉我们该查询发生了什么以及生成了什么 SQL?
  • 我需要加入两个类:FactureEntete 和 FacturePoste 具有多对一的关系,所以其中一个 factureEntete 可能有一个带有 numeroFacture forgeinKey 的可能 FacturePoste
  • 你的问题不清楚。假设 FetchType.EAGER,联接将为您提供父 FacturePosteFactureEntete 子列表,因此可以从结果中访问所有内容。这与您想要的有何不同?

标签: jpa join criteria


【解决方案1】:

您必须传递如下所述的实体图作为查询和传递的提示 仅根在 criteria.select(root) 中。

CriteriaBuilder criteriaBuilder = 
em.getCriteriaBuilder();
CriteriaQuery<FacturePoste> criteria =    
criteriaBuilder.
createQuery(FacturePoste.class);
Root<FacturePoste> root = 
criteria.from(FacturePoste.class);
Join<FacturePoste, FactureEntete> 
contactInfoJoin = 
root.join("numeroFacture");
TypedQuery<FacturePoste> query = 
em.createQuery(criteria.select(root));

 //   Create an entity graph with a subgraph 
 EntityGraph<FacturePoste> graph = 
 em.createEntityGraph(FacturePoste.class);
 graph.addSubgraph("numeroFacture");

 query.setHint("javax.persistence.fetchgraph", 
 graph);

 list = query.getResultList();

 Note:It will be better if you use static 
 meta model instead of passing entity feild.     
 names directly.

【讨论】:

    【解决方案2】:

    如果我们使用multiselect 真的很容易。我会尽量用简单的语言来解释。

    您已经创建了CriteriaBuilder,但您需要为CriteriaQuery 的泛型类型赋予 Object[] 类型,因为来自两个表的数据属于不同的数据类型,因此我们将它们放入 List对象:

    CriteriaQuery<Object[]> criteria = criteriaBuilder.createQuery(Object[].class);
    

    这意味着查询将从两个表中获取数据作为对象。

    进一步,您为 FacturePoste 类创建了 Root,但您还需要为 FactureEntete 创建 Root:

    Root<FacturePoste> posteRoot = cq.from(FacturePoste.class);
    Root<FactureEntete> enteteRoot = cq.from(FactureEntete.class);
    

    现在我们将对查询执行multiselect 操作:

    criteria.multiselect(posteRoot,enteteRoot);
    

    然后您可以执行TypedQuery,但这里也可以使用 Object[] 作为通用类型:

    TypedQuery<Object[]> query = em.createQuery(criteria);
    

    希望这会有所帮助!

    PS:我的这种方法不需要Join,你可以根据自己的需要自定义查询。示例:

    criteria.multiselect(posteRoot,enteteRoot).where(cb.equal(posteRoot.get("id"), enteteRoot.get("posteId")));
    

    如果 FacturePosteFactureEntete 映射为 FactureEntete 是 ManyToOne 到 FacturePoste,外键为 posteId,则只会获取与 ar 相关的数据。

    【讨论】:

    • 您也可以使用 join 来实现,但您需要创建一个 DTO,您可以在其中指定需要在结果中显示的字段。因为使用普通连接,我们将始终使用 CriteriaQuery ,它只给出该实体的结果。这就是为什么我更喜欢这种方法而不是 Join
    猜你喜欢
    • 2012-04-16
    • 2019-06-17
    • 2021-10-11
    • 2022-01-22
    • 2013-10-08
    • 2018-03-09
    • 1970-01-01
    • 1970-01-01
    • 2015-07-05
    相关资源
    最近更新 更多