问题描述
我的架构将类似于上图。
我打算使用 Spring 数据 JDBC 并发现
如果多个聚合引用同一个实体,则该实体不能成为引用它的聚合的一部分,因为它只能是一个聚合的一部分。
以下是我的问题:
- 如何在不改变数据库设计的情况下为上述创建两个不同的聚合?
- 如何单独检索订单/供应商列表?即我不想遍历聚合根。
解决方法
如何在不改变数据库设计的情况下为上述创建两个不同的聚合?
我认为这里只有三个聚合:订单、供应商和产品类型。我经常使用的心理测试是:
如果 A
有对 B
的引用并且我删除了一个 A
,我是否应该自动且无例外地删除该 B
引用的所有 A
?如果是这样,B
是 A
聚合的一部分。
对于图表中的任何关系来说,这似乎都不是真的,所以让我们为每个实体使用单独的聚合。
这反过来又使图表中的每个引用在不同的聚合之间成为一个引用。
如 "Spring Data JDBC,References,and Aggregates" 中所述,这些必须在您的 Java 代码中建模为 id,而不是 Java 引用。
class Order {
@Id
Long orderid;
String name;
String description;
Instance created;
Long productTypeId;
}
class Vendor {
@Id
Long vid;
String name;
String description;
Instance created;
Long productTypeId;
}
class ProductType {
@Id
Long pid;
String name;
String description;
Instance created;
}
由于它们是单独的聚合,每个聚合都有自己的存储库。
interface Orders extends CrudRepository<Order,Long>{
}
interface Vendors extends CrudRepository<Vendor,Long>{}
interface ProductTypes extends CrudRepository<ProductType,Long>{}
在这一点上,我认为我们满足了您的要求。您可能需要添加一些 @Column
和 @Table
注释才能获得所需的确切名称或提供 NamingStrategy
。
您可能还希望对产品类型进行某种缓存,因为我预计它们会看到大量读取,而只有少量写入。
当然,您可以向存储库添加其他方法,例如:
interface Orders extends CrudRepository<Order,Long>{
List<Orders> findByProductTypeId(Long productTypeId);
}