我的 Java bean 有一个 childCount 属性。此属性未映射到数据库列。相反,它应该由数据库使用COUNT()
对我的 Java bean 及其子项的连接进行操作的函数来计算。如果可以按需/“懒惰地”计算此属性会更好,但这不是强制性的。
在最坏的情况下,我可以使用 HQL 或 Criteria API 设置此 bean 的属性,但我不希望这样做。
Hibernate@Formula
注释可能会有所帮助,但我几乎找不到任何文档。
非常感谢任何帮助。谢谢。
我的 Java bean 有一个 childCount 属性。此属性未映射到数据库列。相反,它应该由数据库使用COUNT()
对我的 Java bean 及其子项的连接进行操作的函数来计算。如果可以按需/“懒惰地”计算此属性会更好,但这不是强制性的。
在最坏的情况下,我可以使用 HQL 或 Criteria API 设置此 bean 的属性,但我不希望这样做。
Hibernate@Formula
注释可能会有所帮助,但我几乎找不到任何文档。
非常感谢任何帮助。谢谢。
JPA 不提供对派生属性的任何支持,因此您必须使用提供者特定的扩展。正如您所提到的,@Formula
在使用 Hibernate 时非常适合。您可以使用 SQL 片段:
@Formula("PRICE*1.155")
private float finalPrice;
甚至是对其他表的复杂查询:
@Formula("(select min(o.creation_date) from Orders o where o.customer_id = id)")
private Date firstOrderDate;
id
当前实体的在哪里id
。
以下博客文章值得一读:Hibernate Derived Properties - Performance and Portability。
如果没有更多细节,我无法给出更准确的答案,但上面的链接应该会有所帮助。
你有三个选择:
@Transient
方法计算属性@PostLoad
实体侦听器@Formula
注释虽然 Hibernate 允许您使用@Formula,但在 JPA 中,您可以使用@PostLoad回调来使用一些计算的结果填充瞬态属性:
@Column(name = "price")
private Double price;
@Column(name = "tax_percentage")
private Double taxes;
@Transient
private Double priceWithTaxes;
@PostLoad
private void onLoad() {
this.priceWithTaxes = price * taxes;
}
因此,您可以像这样使用 Hibernate @Formula
:
@Formula("""
round(
(interestRate::numeric / 100) *
cents *
date_part('month', age(now(), createdOn)
)
/ 12)
/ 100::numeric
""")
private double interestDollars;
看看Blaze-Persistence Entity Views,它在 JPA 之上工作并提供一流的 DTO 支持。您可以将任何内容投影到实体视图中的属性,如果可能,它甚至会重用现有的连接节点进行关联。
这是一个示例映射
@EntityView(Order.class)
interface OrderSummary {
Integer getId();
@Mapping("SUM(orderPositions.price * orderPositions.amount * orderPositions.tax)")
BigDecimal getOrderAmount();
@Mapping("COUNT(orderPositions)")
Long getItemCount();
}
获取这个将生成一个类似于这个的 JPQL/HQL 查询
SELECT
o.id,
SUM(p.price * p.amount * p.tax),
COUNT(p.id)
FROM
Order o
LEFT JOIN
o.orderPositions p
GROUP BY
o.id
这是一篇关于自定义子查询提供程序的博客文章,您可能也会感兴趣:https ://blazebit.com/blog/2017/entity-view-mapping-subqueries.html