多个实体的通用JPA存储库

时间:2015-10-01 06:09:20

标签: java spring jpa spring-data

我有几个实体并使用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

2 个答案:

答案 0 :(得分:1)

您可以使用实体继承并使用Spring Expression Language(SpEL)在正确的实体上进行存储库问题调用。就像我上一次更新here

一样

答案 1 :(得分:0)

<块引用>

这种使用通用 SpecBuilder 的设计是否干净?

取决于您对简洁设计的标准。相同的 MyQueryDescriptor 是否适用于不同的实体?当然,它们具有不同的属性,因此您需要问问自己给定的 MyQueryDescriptor 是否会被错误地用于不兼容的实体以及您可以采取哪些方法来防止它。我们无法对此发表评论,因为我们不知道您的 SpecBuilder 是如何工作的。

<块引用>

有没有办法避免为每个实体编写这些存储库接口?假设一个 > 通用存储库?

没有。不过,它也不是很多样板。

<块引用>
  1. MyQueryDescriptor 类有一个方法可以返回一个实例 一个实体,将被查询。什么是获得的干净方式 基于实体类的相应存储库,避免切换 案例?

我想您可以在运行时使用 getBeanProvider,您可以将 resolvableType 定义为 CrudRepository<MyEntityType, IdType>

但是,如果我是你,我会考虑改用 JPA Criteria API,而不是在它之上使用 JpaSpecificationExecutor 抽象。那可能会被证明是更自然的。 Spring 存储库的设计以存储库围绕给定的特定实体组织查询的想法为中心,而您的用例似乎正好相反 - 动态选择一个实体,然后找到一个适合的存储库,只是为了满足 Spring 的限制。在这方面,您似乎在与框架作斗争。