如何编写JPA查询来填充数据传输对象(与我的@Entity对象不同)? [英] How do I write a JPA query to populate a data transfer object (different than my @Entity object)?

查看:273
本文介绍了如何编写JPA查询来填充数据传输对象(与我的@Entity对象不同)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们使用Java 6,JPA 2.1和Hibernate 4.3.6.Final。我有下面的代码,找到我们的组织对象... ... $ / b>

  final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); 
final CriteriaQuery<组织> criteria = builder.createQuery(Organization.class);
final Root<组织> root = criteria.from(Organization.class);
$ b $ final CriteriaQuery query = buildCriteriaQuery(builder,criteria,root,country,state,organizationalTypes,parentOrg,zipCode);
final TypedQuery<组织> typedQuery = entityManager.createQuery(query);
if(page!= null&&page;!= null)
{
int first =(page - 1)* pageSize;
typedQuery.setFirstResult(first);
typedQuery.setMaxResults(pageSize);
} // if
return typedQuery.getResultList();

这些组织对象是数据密集型的对象。我们有一个数据传输对象OrganizationDto,它只包含Organization的一部分字段。有没有办法配置上述内容来填充OrganizationDto对象而不是组织对象?我想避免的是获取结果集,然后编写for循环来遍历所有结果集并创建所有数据传输对象。如果查询能够以某种方式立即填充这些数据传输对象,那将是非常棒的。

有几个例子在JPA 2.1规范中称为构造函数表达式,它允许查询使用任何pojo的构造函数来返回实例。构造函数必须将选择列表作为参数。使用JPQL编写的示例中的示例:

 SELECT NEW com.acme.example.CustomerDetails(c.id,c .status,o.quantity)
FROM Customer c JOIN c.orders o
WHERE o.quantity> 100

将使用类型查询创建为:

  CriteriaQuery< CustomerDetails> q = 
cb.createQuery(CustomerDetails.class);
根< Customer> c = q.from(Customer.class);
加入<客户,订单> o = c.join(Customer_.orders);
q.where(cb.gt(o.get(Order_.quantity),100));
q.select(cb.construct(CustomerDetails.class,
c.get(Customer_.id),
c.get(Customer_.status),
o.get订单数量)));

假设CustomerDetail的构造函数存在于ID,状态和数量字段中,那么查询会返回这些实例而不是实体。

We’re using Java 6, JPA 2.1, and Hibernate 4.3.6.Final. I have the below code that finds our Organization objects …

    final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    final CriteriaQuery<Organization> criteria = builder.createQuery(Organization.class);
    final Root<Organization> root = criteria.from(Organization.class);

    final CriteriaQuery query = buildCriteriaQuery(builder, criteria, root, country, state, organizationTypes, parentOrg, zipCode);
    final TypedQuery<Organization> typedQuery = entityManager.createQuery(query);
    if (page != null && pageSize != null)
    {
        int first = (page - 1) * pageSize;
        typedQuery.setFirstResult(first);
        typedQuery.setMaxResults(pageSize);
    }   // if
    return typedQuery.getResultList();

These Organization objects are very data-intensive objects. We have a data transfer object, OrganizationDto, which only contains a subset of the fields of Organization. Is there a way to configure the above to populate the OrganizationDto objects instead of the Organization objects? What I would like to avoid is getting the result set and then writing a for loop to go through all of it and create all the data transfer objects. It would be great if the query could somehow just populate these data transfer objects right away.

解决方案

There are a few examples of what is called a constructor expression in the JPA 2.1 specification that allow the query to use any pojo's constructor to return instances. The constructor must take the select list as parameters. One the example in the spec written using JPQL:

"SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.quantity)
FROM Customer c JOIN c.orders o
WHERE o.quantity > 100"

would be created with a type query as:

CriteriaQuery<CustomerDetails> q =
cb.createQuery(CustomerDetails.class);
Root<Customer> c = q.from(Customer.class);
Join<Customer, Order> o = c.join(Customer_.orders);
q.where(cb.gt(o.get(Order_.quantity), 100));
q.select(cb.construct(CustomerDetails.class,
 c.get(Customer_.id),
 c.get(Customer_.status),
 o.get(Order_.quantity)));

Assuming a constructor for CustomerDetail exists to take in the ID, status and quantity fields, then the query would return these instances instead of Entities.

这篇关于如何编写JPA查询来填充数据传输对象(与我的@Entity对象不同)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆