我有几个实体并使用Spring Data JPA存储库,specifications查询我的数据库。因此,我创建了一个通用类SpecBuilder
,以根据查询描述(MyQueryDescriptor
)构建我的查询。
public class Specs {
public static <T extends MyEntityIFace> Specification<T> myfind(final MyQueryDescriptor qDesc) {
return new Specification<T>() {
@Override
public Predicate toPredicate(Root<T> root,
CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
try {
return SpecBuilder.mySpec(root, criteriaQuery, criteriaBuilder, qDesc);
} catch (Exception e) {
...handle error...
}
}
};
}
}
我的存储库:
public interface Entity1DAO extends Repository<Entity1,Long>,
JpaSpecificationExecutor {
}
和
public interface Entity2DAO extends Repository<Entity2,Long>,
JpaSpecificationExecutor {
}
现在我有三件事我不太确定:
1)
这种通用SpecBuilder的使用是否干净?
2)
有没有办法避免为每个实体编写那些存储库接口?让我们说一个通用的存储库?
3)
MyQueryDescriptor
类有一个返回实体实例的方法,将被查询
什么是基于实体类获取相应存储库的简洁方法,避免切换案例?我正在考虑将具有特定存储库类的注释添加到每个实体,但感觉有点臭
我应该创建一个工厂并注入像
Entity1.class => Entity1DAO
Entity2.class => Entity2DAO
答案 0 :(得分:1)
您可以使用实体继承并使用Spring Expression Language(SpEL)在正确的实体上进行存储库问题调用。就像我上一次更新here
一样答案 1 :(得分:0)
这种使用通用 SpecBuilder 的设计是否干净?
取决于您对简洁设计的标准。相同的 MyQueryDescriptor
是否适用于不同的实体?当然,它们具有不同的属性,因此您需要问问自己给定的 MyQueryDescriptor
是否会被错误地用于不兼容的实体以及您可以采取哪些方法来防止它。我们无法对此发表评论,因为我们不知道您的 SpecBuilder
是如何工作的。
有没有办法避免为每个实体编写这些存储库接口?假设一个 > 通用存储库?
没有。不过,它也不是很多样板。
<块引用>我想您可以在运行时使用 getBeanProvider
,您可以将 resolvableType
定义为 CrudRepository<MyEntityType, IdType>
。
但是,如果我是你,我会考虑改用 JPA Criteria API,而不是在它之上使用 JpaSpecificationExecutor
抽象。那可能会被证明是更自然的。 Spring 存储库的设计以存储库围绕给定的特定实体组织查询的想法为中心,而您的用例似乎正好相反 - 动态选择一个实体,然后找到一个适合的存储库,只是为了满足 Spring 的限制。在这方面,您似乎在与框架作斗争。