首页 > 解决方案 > 使用 JPA 为多个报告查询具有不同复杂 where 子句的视图的最佳方法

问题描述

我正在尝试提出一种基于同一基本实体实现多个报告页面的好方法。

想象一下,我想根据汽车的一些复杂属性生成多个报告——基本相同SELECT且相同,FROM但具有不同的复杂WHERE条款。

报告示例:

最重要的是,我想要一个过滤组件来帮助查找特定案例。我们可以假设所有这些报告的过滤组件都是相同的,因为所有报告的字段/列将(几乎)相同。

最直接的解决方案是使用所有语句创建 20 个视图,创建 20 个实体来映射这些数据库视图,并为所有这些视图创建存储库。但我想这可以以更聪明的方式实现。

我最初的想法是创建一个CarReportBaseEntity包含大约 50 个字段/列的基本实体。

@Entity
@Table(name = "CAR_REPORT_VIEW")
public abstract class CarReportBaseEntity<T extends CarReportBaseEntity<T>> implements Serializable, FilteredEntity<T> {

    @Id
    @Column(insertable = false, updatable = false)
    private Long id;

    @Column(insertable = false, updatable = false)
    private Long manufacturedYear;

    etc...
}

然后对于每个不同的报告,我只需创建一个实体,例如:

@Entity
@Where(clause = "manufacturedYear = 2020")
class ManufacturedIn2020ReportEntity extends CarReportBaseEntity<ManufacturedIn2020ReportEntity> {
}

对于其他报告也是如此:

@Entity
@Where(clause = "some complex where clause")
class SomeOtherReportEntity extends CarReportBaseEntity<SomeOtherReportEntity> {
}

这将允许我通过添加一个类和调整@Where注释来快速创建新报告,包括FilteredEntity. 但是这不起作用,因为它@Inheritance(strategy = InheritanceType.SINGLE_TABLE)默认创建一个,然后破坏整个应用程序,因为我没有DTYPE指定任何列。我不想指定任何内容,我只想为同一个实体创建类,但具有不同的复杂 where 子句。

我能做些什么来优雅地解决这个问题?

标签: javahibernatejpainheritance

解决方案


你只需要:

  • 您已经拥有 CarReportBaseEntity 的实体类
  • 为您的每个报告创建 20 个包含jpa条件的 CriteriaQueries 的工厂
  • 一堆(服务)方法,它们获取 CriteriaQuery 参数并添加进一步过滤(例如whereCarBrandStartsWith(CriteriaQuery q, String prefix)

要获取报告,您需要获取该报告的 CriteriaQuery 对象并获取该结果列表。如果您需要进一步过滤这些结果,您可以将条件对象传递给您想要的服务方法

编辑 1

从那时起,我们将真正从多个类中受益,我们可以为每个报告案例使用特定列/顺序扩展 FilterEntity

您的条件查询不必总是返回 CarReportBaseEntity。对于每个报告,您可以定义您想要的任何选择子句(CriteriaQuery::multiselect)并将结果包装在您想要的任何 dto 中(CriteriaBuilder::createQuery(resultType))。我在这种方法中看到的优点是您可以将所有查询逻辑保存在一个地方,在您的工厂中,而不是将其拆分为 20 个类和多个注释之一。


推荐阅读