使用 Java 泛型进行 JPA findAll() 查询和 WHERE 子句
2022-09-02 00:47:21
所以,经过10多年的休息,我将回到Java并尝试使用JPA和Java泛型的东西。我创建了一个基于泛型的JPA查询,基本上可以findAll(other)
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<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();
}
有什么建议吗?如果有的话,我希望它在那里,以便其他人可以利用它。