我有一个实体,它有多个@ManyToOne
关联的对象。目前,我将所有相关对象获取类型建模为LAZY
。
实际上,我正在编写REST API
以支持各种功能,例如
- 获取一个
@ManytoOne
注释解析为仅 id 的实体 - 获取具有
@ManytoOne
注释解析为整个对象的实体 - 获取具有
@ManytoOne
注释解析为部分对象的实体 - 获取
@ManytoOne
注释解析为仅 id 的实体
我的应用程序是使用 spring-boot jpa 存储库构建的。显然,REST API
中的上述变化可以通过为每个API
编写命名查询来解决。如果我这样做,在某一时刻,每个关联的对象都会有多个命名查询。但我期待一种更好的方法来建模和查询实体。
任何建议不胜感激。
根据我的理解,你应该使用Query by Example
按示例查询API 由三部分组成:
- 探测器:具有填充字段的域对象的实际示例。
ExampleMatcher
:ExampleMatcher
包含有关如何匹配特定字段的详细信息。它可以跨多个Examples
重复使用。Example
:Example
由探头和ExampleMatcher
组成。它用于创建查询。按示例查询非常适合多种用例:
- 使用一组静态或动态查询数据存储 约束。
- 频繁重构域对象,无需 担心破坏现有查询。
- 独立工作 从基础数据存储 API。
按示例查询也有几个限制:
- 不支持嵌套或分组属性约束,例如
firstname = ?0 or (firstname = ?1 and lastname = ?2)
.- 仅支持字符串的开始/包含/结束/正则表达式匹配和精确匹配 匹配其他属性类型。
在您的情况下,静态定义结构的查询确实不合适,因为您确实会乘以写入/修改/维护的查询数量.
JPA 和 Spring Data 提供了创建灵活查询和动态设置快速获取的替代方案:
-
JPA 2 - 标准:专注于动态构建查询和急切获取关系.
它功能强大,但需要样板代码的重要组成部分来创建标准。 -
JPA 2.1 - 实体图:专注于预先获取关系.
专注于热切获取关系.
它非常简单,不需要样板代码.
只需在您创建的Query/Criteria
中添加提示。
它可以与 JPQL 查询或条件一起使用。 -
Spring 数据 - 规格 : 专注于动态构建查询。 它是具有领域驱动设计愿景的JPA标准的包装器/增强器。它功能强大,但设置起来也很冗长。
-
Spring 数据 - 按示例查询:专注于动态构建查询。 这非常简单,客户友好。它有一些限制,我不认为 API 旨在设置查询实体关系的获取模式。
为了满足您的要求,我将介绍两种存储库方法.
第一个将使用标准 + 实体图来受益于动态构建查询和为这些情况设置关系的快速获取的简单方法:
获取@ManytoOne注释解析为仅 id 的实体
获取具有@ManytoOne注释解析为整个对象的实体
获取@ManytoOne注释解析为分部对象的实体
第二种方法将使用实体图+ JPQL来仅从对此方法的快速获取中受益:
获取@ManytoOne注释解析为仅 id 的实体
使用条件 + 实体图,您可以获得一个执行所有操作的单个方法,但拥有一个执行许多操作的复杂方法不一定是最佳选择。