选择多个列并将其设置为DTO列表

时间:2015-12-19 14:35:47

标签: mysql sql database jpa jpql

我希望在单个查询中从数据库中获取多个列,并将其设置为相应的DTO对象字段。

错误讯息:

java.lang.IllegalStateException: No data type for node:
org.hibernate.hql.internal.ast.tree.IdentNode
 +-[IDENT] IdentNode: 'payment' {originalText=payment}

查询:

TypedQuery<Object[]> query = entityManager.createQuery("SELECT
payment, createdOn,responseMessage FROM PaymentLog log WHERE log.id
=:personId", Object[].class);

query.setParameter("personId",new BigInteger(basicEntityDto.getId()));
List<Object[]> results =  query.getResultList();

for (Object[] log : results) {
   paymentTransaction.setAmount(log[0].toString());
   paymentTransaction.setDate(log[1].toString());
   paymentTransaction.setDescription(log[2].toString());
   transactionList.add(paymentTransaction);
}

P.S。我知道我可以使用JPA构造函数表达式。但是因为我必须在DTO列表中添加DTO(即transactionList),所以有一种方法可以使用JPA构造表达式,我可以通过在每个DTO的循环中仅运行一次查询来实现这一点吗?

2 个答案:

答案 0 :(得分:0)

您可以让JPA提供程序通过构造函数表达式为您转换结果集:

http://www.objectdb.com/java/jpa/query/jpql/select#Result_Classes_Constructor_Expressions_

https://en.wikibooks.org/wiki/Java_Persistence/JPQL#Constructors

这要求指定的类具有与select表达式匹配的构造函数。这将看起来像下面这样:

TypedQuery<PaymentTransaction> query = entityManager.createQuery("SELECT new PaymentTransaction (log.payment, log.createdOn, log.responseMessage ) FROM PaymentLog log WHERE log.id
=:personId", PaymentTransaction.class);
query.setParameter("personId",new BigInteger(basicEntityDto.getId()));
List<PaymentTransaction> results =  query.getResultList();

在JPA 2.1中,您也可以如下所示:

https://en.wikibooks.org/wiki/Java_Persistence/Querying#ConstructorResult_.28JPA_2.1.29

答案 1 :(得分:0)

你能做的是:

TypedQuery<PaymentLog> query = entityManager.createQuery("SELECT log FROM PaymentLog log WHERE log.id =:personId", PaymentLog.class);

query.setParameter("personId",new BigInteger(basicEntityDto.getId()));
List<PaymentLog> results =  query.getResultList();

for (PaymentLog log : results) {
   paymentTransaction.setAmount(log.getPayment());
   paymentTransaction.setDate(log.getCreatedOn());
   paymentTransaction.setDescription(log.getResponseMessage());
   transactionList.add(paymentTransaction);
}

如果您不打算使用它,那么从数据库中选择所有内容并不是一个好主意。如果所选字段是表中唯一的列,那么接近上面的工作。

如果表格中有更多列,前一个列仍然可以使用,但这可能更好:

TypedQuery<PaymentTransaction> query = entityManager.createQuery("SELECT new PaymentTransaction (log.payment, log.createdOn, log.responseMessage) FROM PaymentLog log WHERE log.id =:personId", PaymentTransaction.class);
query.setParameter("personId",new BigInteger(basicEntityDto.getId()));
List<PaymentTransaction> results =  query.getResultList();

上述查询将返回已创建的PaymentTransactions列表。您必须注意,类PaymentTransaction应该有一个构造函数,它以给定的顺序接受这些字段。否则会导致异常