JPA和标准API - 只选择特定的列(JPA & Criteria API - Select o

2019-06-18 08:37发布

我想只选择特定的列(例如: SELECT a FROM b )。 我有一个通用的DAO和我想出是:

public List<T> getAll(boolean idAndVersionOnly) {
    CriteriaBuilder builder = manager.getCriteriaBuilder();
    CriteriaQuery<T> criteria = builder.createQuery(entityClazz);
    Root<T> root = criteria.from(entityClazz);
    if (idAndVersionOnly) {
        criteria.select(root.get("ID").get("VERSION")); // HERE IS ERROR
    } else {
        criteria.select(root);
    }
    return manager.createQuery(criteria).getResultList();
}

和错误是: The method select(Selection<? extends T>) in the type CriteriaQuery<T> is not applicable for the arguments (Path<Object>) 我应该如何改变这种状况? 我希望得到一个类型T具有唯一对象IDVERSION领域,其他都是null

T延伸AbstractEntity具有那些2个字段。

entityClazzT.class

Answer 1:

其中一个JPA途径只得到特定列是要求一个元组对象。

在你的情况,你需要写是这样的:

CriteriaQuery<Tuple> cq = builder.createTupleQuery();
// write the Root, Path elements as usual
Root<EntityClazz> root = cq.from(EntityClazz.class);
cq.multiselect(root.get(EntityClazz_.ID), root.get(EntityClazz_.VERSION));  //using metamodel
List<Tuple> tupleResult = em.createQuery(cq).getResultList();
for (Tuple t : tupleResult) {
    Long id = (Long) t.get(0);
    Long version = (Long) t.get(1);
}

如果你有代表结果的一类,就像另一种方法是可以T ,你的情况。 T并不需要是一个实体类。 如果T有一个构造函数,如:

public T(Long id, Long version)

那么你可以使用T直接在CriteriaQuery的构造函数:

CriteriaQuery<T> cq = builder.createQuery(T.class);
// write the Root, Path elements as usual
Root<EntityClazz> root = cq.from(EntityClazz.class);
cq.multiselect(root.get(EntityClazz_.ID), root.get(EntityClazz_.VERSION));  //using metamodel
List<T> result = em.createQuery(cq).getResultList();

看到这个链接进行进一步的参考。



Answer 2:

cq.select(cb.construct(entityClazz.class, root.get("ID"), root.get("VERSION")));  // HERE IS NO ERROR

https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/Criteria#Constructors



Answer 3:

首先,我真的不明白你为什么会想只有ID和版本的对象,和其他所有的道具是空值。 然而,这里是一些代码,会为你做的(不使用JPA他们,但正常休眠。我相信你可以找到等价于JPA或简单地获得Hibernate的Session从EM代表的obj 从EJB访问Hibernate的Session使用EntityManager的 ):

List<T> results = session.createCriteria(entityClazz)
    .setProjection( Projections.projectionList()
        .add( Property.forName("ID") )
        .add( Property.forName("VERSION") )
    )
    .setResultTransformer(Transformers.aliasToBean(entityClazz); 
    .list();

这将返回有他们的ID和版本设置和所有其他道具为null对象的名单,因为aliasToBean变压器将无法找到他们。 同样,我不确定我能想到的情况,我想这样做。



Answer 4:

你可以做这样的事情

Session session = app.factory.openSession();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery query = builder.createQuery();
Root<Users> root = query.from(Users.class);
query.select(root.get("firstname"));
String name = session.createQuery(query).getSingleResult();

在这里您可以更改“名字”你想要的列的名称。



文章来源: JPA & Criteria API - Select only specific columns