java - 使用 JPA 为多个报告查询具有不同复杂 where 子句的视图的最佳方法
问题描述
我正在尝试提出一种基于同一基本实体实现多个报告页面的好方法。
想象一下,我想根据汽车的一些复杂属性生成多个报告——基本相同SELECT
且相同,FROM
但具有不同的复杂WHERE
条款。
报告示例:
- R1:在B至C期间进行过检查的所有品牌A的汽车列表,安装了D件,在E国使用。
- R2:今年生产的所有汽车清单
- ...
- R20:...列表
最重要的是,我想要一个过滤组件来帮助查找特定案例。我们可以假设所有这些报告的过滤组件都是相同的,因为所有报告的字段/列将(几乎)相同。
最直接的解决方案是使用所有语句创建 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 子句。
我能做些什么来优雅地解决这个问题?
解决方案
你只需要:
- 您已经拥有 CarReportBaseEntity 的实体类
- 为您的每个报告创建 20 个包含jpa条件的 CriteriaQueries 的工厂
- 一堆(服务)方法,它们获取 CriteriaQuery 参数并添加进一步过滤(例如
whereCarBrandStartsWith(CriteriaQuery q, String prefix)
)
要获取报告,您需要获取该报告的 CriteriaQuery 对象并获取该结果列表。如果您需要进一步过滤这些结果,您可以将条件对象传递给您想要的服务方法
编辑 1:
从那时起,我们将真正从多个类中受益,我们可以为每个报告案例使用特定列/顺序扩展 FilterEntity
您的条件查询不必总是返回 CarReportBaseEntity。对于每个报告,您可以定义您想要的任何选择子句(CriteriaQuery::multiselect)并将结果包装在您想要的任何 dto 中(CriteriaBuilder::createQuery(resultType))。我在这种方法中看到的优点是您可以将所有查询逻辑保存在一个地方,在您的工厂中,而不是将其拆分为 20 个类和多个注释之一。
推荐阅读
- vba - VBA 抓取:需要对象
- user-interface - 如何在 C# 中使用和访问 ListBoxItem 的 IsVisible 属性
- c++ - 向量有什么区别
() 与向量 {} vs NULL vs size=0? - javascript - 如何在 Angular / TypeScript 项目中使用 IScroll
- javascript - 通过jquery重新排列html
- python - Python无法从XML中的父标签获取子标签及其值
- jquery - 单击父级时触发单击
- r - 按年份绘制发病率,使 10 度的斜率代表 1% 的年度百分比变化
- vb.net - KeyDown 和 KeyUp 组合(例如 Ctrl+A) KeyUp 有效,而不是 KeyDown
- javascript - 在返回承诺中执行 .then()