使用JPA选择非实体?

xbp102n0  于 2023-10-19  发布在  其他
关注(0)|答案(4)|浏览(142)

JPA是否可以使用原生查询检索非实体类的示例?
我有一个非实体类,它 Package 了两个实体:

class Wrap{
  Entity1 ent1;
  Entity2 ent2
}
@Entity
class Entity1{
  ...
}
@Entity
class Entity2{
  ...
}

我怎么能做这种事?

Query q = entityManager.createNativeQuery("native select here");
List<Wrap> list = q.getResultList();
r7knjye2

r7knjye21#

JPA是否可以使用原生查询检索非实体类的示例?
不可以。原生查询只能返回实体 *(如果您通过将resultClassresultSetMapping传递给createNativeQuery方法来告诉它们这样做;如果不这样做,您将得到原始数据集合)。
在JPQL中,你可以使用构造函数表达式(SELECT NEW...)和非实体构造函数。但是这不支持原生查询,你必须手动操作。

vkc1a9a2

vkc1a9a22#

我是这样做的。
我有很多字段的实体

@Entity
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "outcoming_transaction", schema = "ibank_schema", catalog = "ibank")
public class OutcomingTransaction {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false)
    private Long id;

    @NotEmpty(message = "Sender name cant be empty")
    @Size(max = 255, message = "Max size for sender name is 255 characters")
    @Column(name = "sender_name", updatable = false)
    private String senderName;

    @NotEmpty(message = "Sender surname cant be empty")
    @Size(max = 255, message = "Max size for sender surname is 255 characters")
    @Column(name = "sender_surname", updatable = false)
    private String senderSurname;

    @NotEmpty(message = "Sender account number cant be empty")
    @Size(max = 20, message = "Max size for sender account number is 20 characters")
    @Column(name = "sender_account_number", updatable = false)
    private String senderAccountNumber;

    @NotNull(message = "Money amount cant be empty")
    @Column(name = "money_amount", updatable = false)
    private BigDecimal moneyAmount;

    @NotEmpty(message = "Currency code cant be empty")
    @Size(max = 3, message = "Max size for currency code is 3 characters")
    @Column(name = "currency_code", updatable = false)
    private String currencyCode;

    @NotEmpty(message = "Recipient account number cant be empty")
    @Size(max = 20, message = "Max size for recipient account number is 20 characters")
    @Column(name = "recipient_account_number", updatable = false)
    private String recipientAccountNumber;

    @NotEmpty(message = "Recipient name cant be empty")
    @Size(max = 255, message = "Max size for recipient name is 255 characters")
    @Column(name = "recipient_name", updatable = false)
    private String recipientName;

    @NotEmpty(message = "Recipient surname cant be empty")
    @Size(max = 255, message = "Max size for sender surname is 255 characters")
    @Column(name = "recipient_surname", updatable = false)
    private String recipientSurname;

    @ManyToOne
    @JoinColumn(name = "recipient_bank", referencedColumnName = "id")
    @Valid // todo 30.08.2023 Anton - check if this working fine
    @NotNull(message = "Recipient bank cant be empty")
    private BankData recipientBank;

    @Size(max = 255, message = "Max size for payment purpose is 255 characters")
    @Column(name = "payment_purpose", updatable = false)
    private String paymentPurpose;

    @NotNull(message = "Transaction fee have to be filled up")
    @Column(name = "transaction_fee", updatable = false)
    private BigDecimal transactionFee;

    @Column(name = "transaction_time", updatable = false)
    private Timestamp transactionTime;


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        OutcomingTransaction that = (OutcomingTransaction) o;
        return id.equals(that.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    public String toString() {
        return transactionTime.toString() + ": from " + senderSurname + " " + senderName + " to " + recipientSurname + " " + recipientName;
    }
}

因此,我有吨的交易,我需要得到每种货币的总和。资料档案库:

@Repository  
public interface OutcomingTransactionRepository extends JpaRepository<OutcomingTransaction, Long> {  
   
@Query("SELECT NEW ru.k2.ibank.model.dto.TransactionSummaryDTO(t.currencyCode, SUM(t.moneyAmount)) FROM OutcomingTransaction t " +  
"WHERE t.transactionTime BETWEEN :dateFrom AND :dateTill " +  
"GROUP BY t.currencyCode")  
List<TransactionSummaryDTO> getSumWithinTimeWindow(  
@Param("dateFrom") Timestamp dateFrom,  
@Param("dateTill") Timestamp dateTill);  
  
}

DTO

@Getter
@Setter
@NoArgsConstructor
public class TransactionSummaryDTO {

    public TransactionSummaryDTO(String currencyCode, BigDecimal totalAmount) {
        this.currencyCode = currencyCode;
        this.totalAmount = totalAmount;
    }

    private String currencyCode;
    private BigDecimal totalAmount;

}

下面是JSON回复:

[
    {
        "currencyCode": "CNY",
        "totalAmount": 15120.25
    },
    {
        "currencyCode": "EUR",
        "totalAmount": 17850.25
    },
    {
        "currencyCode": "RUB",
        "totalAmount": 1233.54
    },
    {
        "currencyCode": "USD",
        "totalAmount": 15437306.50
    },
    {
        "currencyCode": "GBP",
        "totalAmount": 123450.25
    }
]
yzxexxkh

yzxexxkh3#

没有实体的JPA原生查询-特别是复杂查询(递归,多个连接等)?
这对我来说很有效,但它是特定于Hibernate的:

import org.hibernate.transform.Transformers;

Query query = entityManagerFactory.createEntityManager().createNativeQuery(SQL);
// Transform the results to MAP <Key, Value>
query.unwrap(org.hibernate.SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
query.setParameter("myNamedParam", myParam);
List<Map<String, Object>> list = query.getResultList();
for (Map<String, Object> map : list) {
    System.out.println(map);
}

参见https://www.programmerall.com/article/89371766511/

wwtsj6pe

wwtsj6pe4#

我想我找到解决办法了。有一种方法可以在构造查询时使用NEW关键字。我做了什么来解决这个问题:

public List<ProductType> getProductByName(String productName) {
        String sqlQuery = "select DISTINCT **NEW** project1.ProductType(o.name, o.revision) from Lhproduct o where o.name = :prodname";
        Query qry = getEntityManager().**createQuery(sqlQuery);**
        qry.setParameter("prodname",productName);
        return qry.getResultList();
 }

ProductType是一个非实体对象,一个实现Serialialabale的简单普通对象。但是你需要定义合适的构造函数。
Happy coding:-)
谢谢你和问候,哈里。

相关问题