JPA Criteria API – 如何添加JOIN子句(作为一般句子)
我试图动态构造查询,我的下一个目标是添加JOIN子句(我不知道如何使用API)。
例如,到目前为止,这段代码对我有用:
... 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实现)
我的愿望是添加JOIN子句(尽可能通用)!
我在类中有特定的注释(this.baseClass)
例如 :
@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "assay_id", nullable = false)
那么,在标准JPA中有没有这样的方法呢? (注意:这不编译)
这是一个实际的失败方法:
... Join experimentAssays = entity_.join( entity_.get("assay_id") );
或者像那样:
... CriteriaQuery q = cb.createQuery(Customer.class); Root c = q.from(Customer.class); SetJoin o = c.join(Customer_.orders);
对我来说,如果它可能更加通用,它会很棒……:
... Join joinClause = entity_join(entity_.get("assay_id"), entity2_.get("id"));
当然,我在类中有特定的注释(this.baseClass)
感谢您的时间。 我会感谢各种评论!
也许从第23章 – 使用Criteria API创建 Java EE 6教程查询的以下摘录将会有所启发(实际上,我建议阅读整个第23章):
使用连接查询关系
对于导航到相关实体类的查询,查询必须通过调用查询根对象或另一个
join
对象上的一个From.join
方法来定义与相关实体的join
。 连接方法类似于JPQL中的JOIN
关键字。连接的目标使用
EntityType
类型的Metamodel类来指定已连接实体的持久字段或属性。join方法返回
Join
类型的对象,其中X
是源实体,Y
是连接的目标。示例23-10加入查询
CriteriaQuery
cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel(); EntityType Pet_ = m.entity(Pet.class); Root pet = cq.from(Pet.class); Join owner = pet.join(Pet_.owners); 可以将连接链接在一起以导航到目标实体的相关实体,而无需为每个连接创建
Join
实例。示例23-11在查询中将联接链接在一起
CriteriaQuery
cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel(); EntityType Pet_ = m.entity(Pet.class); EntityType Owner_ = m.entity(Owner.class); Root pet = cq.from(Pet.class); Join address = cq.join(Pet_.owners).join(Owner_.addresses);
话虽如此,我还有一些补充意见:
首先,代码中的以下行:
Root entity_ = cq.from(this.baseClass);
让我觉得你错过了静态元模型类部分。 引用示例中的元模型类(如Pet_
用于描述持久类的元信息 。 它们通常使用注释处理器( 规范元模型类 )生成,或者可以由开发人员编写( 非规范元模型 )。 但是你的语法看起来很奇怪,我想你正试图模仿你错过的东西。
其次,我真的认为你应该忘记这个assay_id
外键,你在这里走错路。 你真的需要开始思考对象和关联,而不是表和列。
第三,我并不确定通过添加JOIN子句尽可能通用以及你的对象模型看起来完全理解你的意思,因为你没有提供它(见前一点)。 因此,更准确地回答你的问题是不可能的。
总而言之,我认为您需要阅读更多有关JPA 2.0 Criteria和Metamodel API的内容,我热烈推荐以下资源作为起点。
也可以看看
- JPA 2.0规范中的6.2.1静态元模型类
- JPA 2.0中的动态,类型安全查询
- 使用Criteria API和Metamodel API创建基本类型安全查询
相关问题
- 如何生成JPA 2.0元模型?
实际上,如果您的注释正确,则不必处理静态元模型。
你可以用这个:
CriteriaQuery cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel(); EntityType petMetaModel = m.entity(Pet.class); Root pet = cq.from(Pet.class); Join owner = pet.join(petMetaModel.getSet("owners", Owner.class));
您不需要学习JPA。 您可以使用我的简单标准JPA2( https://sourceforge.net/projects/easy-criteria/files/ )。 这是一个例子
CriteriaComposer petCriteria CriteriaComposer.from(Pet.class). where(Pet_.type, EQUAL, "Cat").join(Pet_.owner).where(Ower_.name,EQUAL, "foo"); List result = CriteriaProcessor.findAllEntiry(petCriteria);
要么
List result = CriteriaProcessor.findAllTuple(petCriteria);
警告! Sun JPA 2示例中存在大量错误,并且Pascal的答案中出现了粘贴的内容。 请查阅这篇文章 。
这篇文章和Sun Java EE 6 JPA 2的例子确实阻碍了我对JPA 2的理解。在浏览了Hibernate和OpenJPA手册并认为我对JPA 2有了很好的理解后,我在回到这篇文章后仍感到困惑。 。