首先,我知道我们在这里提高了一些标准,但这已经比没有Spring Data JPA的帮助而编写的代码少得多。
其次,如果你要做的只是将调用转发到存储库,那么我首先就不需要服务类。如果你有需要在事务中编排不同存储库的业务逻辑或要封装的其他业务逻辑,我们建议在存储库前面使用服务。
一般来说,你当然可以执行以下 *** 作:
interface ProductRepository<T extends Product> extends CrudRepository<T, Long> { @Query("select p from #{#entityName} p where ?1 member of p.categories") Iterable<T> findByCategory(String category); Iterable<T> findByName(String name);}
这将允许你像这样使用客户端上的存储库:
class MyClient { @Autowired public MyClient(ProductRepository<Car> carRepository, ProductRepository<Wine> wineRepository) { … }}
它将按预期工作。但是,有一些注意事项:
仅当域类使用单表继承时,此方法才有效。我们在引导时可以获得的关于域类的唯一信息是它将是Product对象。因此,对于类似的方法findAll(),甚至findByName(…)相关查询都将以开头select p from Product p where…。这是由于以下事实:反射查找将永远无法生成,Wine或者Car 除非你为其创建专用的存储库接口以捕获具体的类型信息。
一般而言,我们建议为每个聚合根创建存储库接口。这意味着你本身没有每个域类的存储库。更重要的是,基于存储库的服务的1:1抽象也完全没有意义。如果你构建服务,则不会为每个存储库都构建一个服务(猴子可以做到,而我们不是猴子,对吗?;)。服务正在公开一个更高级别的API,更多地是用例驱动,并且通常协调对多个存储库的调用。
另外,如果你在存储库之上构建服务,通常需要强制客户端使用服务而不是存储库(此处的经典示例是,用于用户管理的服务还会触发密码生成和加密,因此决不会最好让开发人员直接使用存储库,因为他们可以有效地解决加密问题。因此,你通常希望对谁可以保留哪些域对象保持选择性,而不是在整个地方都没有创建依赖项。
摘要
是的,你可以构建通用存储库并将其与多种域类型一起使用,但是存在相当严格的技术限制。但是,从架构的角度来看,你上面描述的场景甚至都不会d出,因为这意味着你无论如何都面临着设计的气味。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)