有没有办法减少与CriteriaQuery相关的样板代码量(在JPA 2.0中)?

我喜欢类型安全CriteriaQuery带来的JPA 2.0,但它也带来了一些锅炉板代码。 例如,假设我有一个名为NamedEntity的实体,它只有一个id和一个名为“name”的String字段(假设它将唯一约束设置为true)。 以下是NamedEntityManager的外观:

public class NamedEntityManager { //inject using your framework EntityManager entityManager; //retrieve all existing entities of type NamedEntity from DB public Iterable queryAll() { CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery query = builder.createQuery(NamedEntity.class); return entityManager.createQuery(query).getResultList(); } //retrieve a single entity of type NamedEntity from DB using specified name public NamedEntity queryByName(String name) { CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery query = builder.createQuery(NamedEntity.class); Root root = query.from(NamedEntity.class); query = query.where(root.get("name").in(name)); //skipped the try/catch block for the sake of brevity return entityManager.createQuery(query).getSingleResult(); } } 

有没有办法压缩代码,以避免复制/粘贴相同的代码行到每个查询方法? 也许以某种方式重用CriteriaQuery对象?

我正在寻找类似的东西,你可以看一下可以将JPA作为后端的Querydsl (LGPL许可)。

我还在读它,但从他们的例子来看,它看起来很干净。

 HQLQuery q = new HibernateQuery(session); QCat cat = new QCat("cat"); // query type List cats = q.from(cat).where(cat.name.between("A", "B")).list(cat); 

在JPA 2.1中,很可能将JPQL和Criterias混合在一起。 使用这种方法,您可以使用JPQL定义基本查询,然后使用Criteria API动态添加小部件。

我认为API会更简洁,因为你只需要使用它的一小部分。

似乎没有办法减少代码量。 我想必须牺牲一些东西以获得类型安全性。

方式已过时,这篇文章,但我想添加我最近为简单查询构建的内容

  public static class Jpa2Whatsoever { private final EntityManager em; public class Jpa2WhatsoeverProgress { private CriteriaQuery cq; private List predicates = new ArrayList<>(); private Root root; public Jpa2WhatsoeverProgress(Class type) { this.cq = em.getCriteriaBuilder().createQuery(type); this.root = cq.from(type); } public Jpa2WhatsoeverProgress where(String attributeName, Object value) { Predicate equal = em.getCriteriaBuilder().equal(root.get(attributeName), value); predicates.add(equal); return this; } public List getResultList() { Predicate[] predicatesArray = new Predicate[predicates.size()]; TypedQuery typedQuery = em.createQuery(cq.select(root).where(predicates.toArray(predicatesArray))); List resultList = typedQuery.getResultList(); return Collections.unmodifiableList(resultList); } } public Jpa2Whatsoever(EntityManager entityManager) { this.em = entityManager; } public  Jpa2WhatsoeverProgress select(Class type) { return new Jpa2WhatsoeverProgress(type); } } 

你可以像这样使用它

 List matchingEntities = new Jpa2Whatsoever(entityManager).select(MyEntity.class).where("id", id).where("due", new Date()).getResultList(); 

最后我停止了这个。 主要是因为我看到我只有两个查询,我将不得不扩展DSL以获得所需的查询特征,例如

  • 大于,小于
  • 元模型支持
  • QueryBuilder.currentDate()和类似。

此外,我觉得总是调用where虽然它实际上对应于更多的SQLly and 。 无论如何,如果有人对一个非常简单的查询API感兴趣,它仍然值得一试。

顺便说一句:忘了名字,这只是原型,仅此而已。