繁体   English   中英

如何使用 JPA 和 Hibernate 映射计算的属性

[英]How to map calculated properties with JPA and Hibernate

我的 Java bean 有一个 childCount 属性。 此属性未映射到数据库列 相反,它应该由数据库使用对我的 Java bean 及其子项的连接操作COUNT()函数计算 如果可以按需/“懒惰地”计算此属性会更好,但这不是强制性的。

在最坏的情况下,我可以使用 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 派生属性 - 性能和可移植性

没有更多细节,我无法给出更准确的答案,但上面的链接应该会有所帮助。

也可以看看:

您有三个选择:

  • 要么您使用@Transient方法计算属性
  • 您还可以使用@PostLoad实体侦听器
  • 或者您可以使用 Hibernate 特定的@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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM