使用Javagenerics进行JPA findAll()查询和WHERE子句

因此,经过10年多的休整,我将回到Java并尝试使用JPA和Javagenerics。 我已经基本上创建了一个基于generics的findAll(other) JPA查询

 SELECT * FROM source WHERE other_id = other.id; 

这是我要去的地方。 它有效,但我想知道是否有更好,更清洁的方法来做到这一点。 使用ManagedType很难,而且没有太多完整的文档或简单的例子。

我决定尽可能保持我的代码通用(没有双关语)所以我使用JPA2。

这是所有实体类的根。 我可能不需要它,但它阻止我有基本的错误。

 import java.io.Serializable; public abstract class DomainObject implements Serializable { private static final long serialVersionUID = 1L; public abstract void setId(Long id); public abstract Long getId(); } 

这是抽象的DAO类。 我为实现类扩展了这个,因为我需要更具体地做其他活动 – 主要是确保加载延迟集。

 public abstract class GenericDAOImpl implements GenericDAO { private Class type; @PersistenceContext protected EntityManager entityManager; public GenericDAOImpl(Class type) { super(); this.type = type; } ... save and delete classes go here @Override public List findAll(T2 where) { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(type); Root rootQuery = criteriaQuery.from(type); if (where != null) { EntityType entity = entityManager.getMetamodel().entity(type); SingularAttribute attribute = null; for (SingularAttribute singleAttribute: entity.getSingularAttributes()) { // loop through all attributes that match this class if (singleAttribute.getJavaType().equals(where.getClass())) { // winner! attribute = singleAttribute; break; } } // where t.object = object.getID() criteriaQuery.where(criteriaBuilder.equal(rootQuery.get(attribute), where)); } criteriaQuery.select(rootQuery); TypedQuery query = entityManager.createQuery(criteriaQuery); // need this to make sure we have a clean list? // entityManager.clear(); return query.getResultList(); } 

有什么建议么? 如果有的话,我想要这个,所以其他人可以利用它。

如果您不想将createQueryString一起使用并希望类型安全,请向Adam Bien提示:

  @PersistenceContext EntityManager em; public List allEntries() { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(ConfigurationEntry.class); Root rootEntry = cq.from(ConfigurationEntry.class); CriteriaQuery all = cq.select(rootEntry); TypedQuery allQuery = em.createQuery(all); return allQuery.getResultList(); } 

http://www.adam-bien.com/roller/abien/entry/selecting_all_jpa_entities_as

我发现这个页面非常有用

https://code.google.com/p/spring-finance-manager/source/browse/trunk/src/main/java/net/stsmedia/financemanager/dao/GenericDAOWithJPA.java?r=2

 public abstract class GenericDAOWithJPA { private Class persistentClass; //This you might want to get injected by the container protected EntityManager entityManager; @SuppressWarnings("unchecked") public GenericDAOWithJPA() { this.persistentClass = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } @SuppressWarnings("unchecked") public List findAll() { return entityManager.createQuery("Select t from " + persistentClass.getSimpleName() + " t").getResultList(); } } 

您还可以为所有实体使用名为findAll的namedQuery,并使用entityManager.createNamedQuery(persistentClass.getSimpleName()+"findAll").getResultList(); }在通用FindAll中调用它.getResultList entityManager.createNamedQuery(persistentClass.getSimpleName()+"findAll").getResultList(); } entityManager.createNamedQuery(persistentClass.getSimpleName()+"findAll").getResultList(); }

这将有效,如果您需要where语句,您可以将其添加为参数。

 class GenericDAOWithJPA { 

…….

 public List findAll() { return entityManager.createQuery("Select t from " + persistentClass.getSimpleName() + " t").getResultList(); } }