JPA Criteria API - 如何添加 JOIN 子句(尽可能通用的句子) [英] JPA Criteria API - How to add JOIN clause (as general sentence as possible)

查看:146
本文介绍了JPA Criteria API - 如何添加 JOIN 子句(尽可能通用的句子)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试动态构造查询,我的下一个目标是添加 JOIN 子句(我不知道如何使用 API).

I am trying to construct queries dynamically, and my next target is add JOIN clauses (I don't know how can I use the API).

现在,例如,这段代码对我有用:

By now, for example, this code work for me :

...
Class baseClass;   
...
CriteriaBuilder cb = JpaHandle.get().getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery(this.baseClass);
Root entity_ = cq.from(this.baseClass); 
Predicate restrictions = null;
...
restrictions = cb.conjunction();
restrictions = cb.and(restrictions, entity_.get("id").in(this.listId));
...
cq.where(restrictions);
...
Query qry = JpaHandle.get().createQuery(cq);

(注意:JpaHandle 来自 wicket-JPA 实现)

(Note : JpaHandle is from wicket-JPA implementation)

我的愿望是添加 JOIN 子句(尽可能通用)!

我在类(this.baseClass)中有特定的注释

I have the particular annotations in the classes (this.baseClass)

例如:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "assay_id", nullable = false)

那么,有没有办法在标准 JPA 中做到这一点?(注意:这不会编译)

So,Is there a way to something like this in standard JPA ? (Note : this don't compile)

这里有一个实际的失败方法:

...
Join<Experiment,Assay> experimentAssays = entity_.join( entity_.get("assay_id") );

或者像这样:

...
CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
Root<Customer> c = q.from(Customer.class);
SetJoin<Customer, PurchaseOrder> o = c.join(Customer_.orders);

对我来说,如果它可以更通用,那就太好了......:

For me, if it could be more generical as possible it will be great... :

...
Join joinClause = entity_join(entity_.get("assay_id"), entity2_.get("id"));

当然,我在类(this.baseClass)中有特定的注释

Of course, I have the particular annotations in the classes (this.baseClass)

感谢您的时间.我会感谢所有类型的评论!

Thank you for your time. I'll appreciate all kind of comments!

推荐答案

也许以下摘自 第 23 章 - Java EE 6 教程的第 23 章 - 使用 Criteria API 创建查询 将提供一些启发(实际上,我建议阅读整个第 23 章):

Maybe the following extract from the Chapter 23 - Using the Criteria API to Create Queries of the Java EE 6 tutorial will throw some light (actually, I suggest reading the whole Chapter 23):

对于导航到相关的查询实体类,查询必须定义加入相关实体调用 From.join 方法之一在查询根对象或其他join 对象.加入方法是类似于 JPQL 中的 JOIN 关键字.

Querying Relationships Using Joins

For queries that navigate to related entity classes, the query must define a join to the related entity by calling one of the From.join methods on the query root object, or another join object. The join methods are similar to the JOIN keyword in JPQL.

连接的目标使用元模型类类型EntityType 指定的持久字段或属性加入的实体.

The target of the join uses the Metamodel class of type EntityType<T> to specify the persistent field or property of the joined entity.

join 方法返回一个对象输入 Join,其中 X 是源实体和 Y 是目标加入.

The join methods return an object of type Join<X, Y>, where X is the source entity and Y is the target of the join.

示例 23-10 加入查询

CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Metamodel m = em.getMetamodel();
EntityType<Pet> Pet_ = m.entity(Pet.class);

Root<Pet> pet = cq.from(Pet.class);
Join<Pet, Owner> owner = pet.join(Pet_.owners);

Join 可以链接在一起导航到相关实体目标实体而无需创建每个连接的 Join 实例.

Joins can be chained together to navigate to related entities of the target entity without having to create a Join<X, Y> instance for each join.

示例 23-11 链接连接在一起在查询中

Example 23-11 Chaining Joins Together in a Query

CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Metamodel m = em.getMetamodel();
EntityType<Pet> Pet_ = m.entity(Pet.class);
EntityType<Owner> Owner_ = m.entity(Owner.class);

Root<Pet> pet = cq.from(Pet.class);
Join<Owner, Address> address = cq.join(Pet_.owners).join(Owner_.addresses);

话虽如此,我还有一些补充说明:

That being said, I have some additional remarks:

首先,代码中的以下行:

First, the following line in your code:

Root entity_ = cq.from(this.baseClass);

让我觉得你不知何故错过了静态元模型类部分.引用示例中的Pet_等元模型类用于描述持久化类的元信息.它们通常使用注释处理器生成(规范元模型类),或者可以由开发人员编写(非规范元模型).但是你的语法看起来很奇怪,我想你是在模仿你错过的东西.

Makes me think that you somehow missed the Static Metamodel Classes part. Metamodel classes such as Pet_ in the quoted example are used to describe the meta information of a persistent class. They are typically generated using an annotation processor (canonical metamodel classes) or can be written by the developer (non-canonical metamodel). But your syntax looks weird, I think you are trying to mimic something that you missed.

第二,我真的认为你应该忘记这个 assay_id 外键,你在这里走错了路.您确实需要开始考虑对象和关联,而不是表和列.

Second, I really think you should forget this assay_id foreign key, you're on the wrong path here. You really need to start to think object and association, not tables and columns.

第三,我不太确定通过添加尽可能通用的 JOIN 子句 以及您的对象模型是什么样子,因为您没有提供它(请参阅前一点).因此,无法更准确地回答您的问题.

Third, I'm not really sure to understand what you mean exactly by adding a JOIN clause as generical as possible and what your object model looks like, since you didn't provide it (see previous point). It's thus just impossible to answer your question more precisely.

总而言之,我认为您需要阅读更多有关 JPA 2.0 Criteria 和 Metamodel API 的内容,我热烈推荐以下资源作为起点.

To sum up, I think you need to read a bit more about JPA 2.0 Criteria and Metamodel API and I warmly recommend the resources below as a starting point.

这篇关于JPA Criteria API - 如何添加 JOIN 子句(尽可能通用的句子)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆