因此,经过 10 多年的休息后,我将回到 Java 并尝试使用 JPA 和 Java 泛型。我创建了一个基于泛型的 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 类。我将其扩展为实现类,因为我需要更具体地执行其他 Activity - 主要是确保加载惰性集。
public abstract class GenericDAOImpl<T extends DomainObject, T2 extends DomainObject> implements GenericDAO<T, T2> {
private Class<T> type;
@PersistenceContext
protected EntityManager entityManager;
public GenericDAOImpl(Class<T> type) {
super();
this.type = type;
}
... save and delete classes go here
@Override
public List<T> findAll(T2 where) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(type);
Root<T> rootQuery = criteriaQuery.from(type);
if (where != null) {
EntityType<T> entity = entityManager.getMetamodel().entity(type);
SingularAttribute<? super T, ?> attribute = null;
for (SingularAttribute<? super T, ?> 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<T> query = entityManager.createQuery(criteriaQuery);
// need this to make sure we have a clean list?
// entityManager.clear();
return query.getResultList();
}
有什么建议吗?如果有的话,我希望将其公开,以便其他人可以使用它。
最佳答案
如果您不想将 createQuery
与 String
一起使用并且想要类型安全,请向 Adam Bien 致敬:
@PersistenceContext EntityManager em; public List<ConfigurationEntry> allEntries() { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<ConfigurationEntry> cq = cb.createQuery(ConfigurationEntry.class); Root<ConfigurationEntry> rootEntry = cq.from(ConfigurationEntry.class); CriteriaQuery<ConfigurationEntry> all = cq.select(rootEntry); TypedQuery<ConfigurationEntry> allQuery = em.createQuery(all); return allQuery.getResultList(); }
http://www.adam-bien.com/roller/abien/entry/selecting_all_jpa_entities_as
关于java - 将 Java 泛型用于带有 WHERE 子句的 JPA findAll() 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24572092/