Spring 数据 (JPA) 多个存储库,没有很多 类

Spring Data (JPA) multiple repositories without many classes

在我当前的项目中,我正在使用 Spring Data JPA,并且我有超过 20 个 @Entity 类。

我想为它们创建一个存储库,但是创建另一个 类,每个用于任何模型,带有 @Repository 注释似乎有点矫枉过正,而且很多 "repeated"代码 - 所有存储库 类 将如下所示:

@Repository
public interface SomeModelRepository extends CrudRepository<SomeModel, Long> {
}

有什么方法可以创建 "automagically" 那些存储库?并且只指定那些我将用我自己的方法扩展的?应该如何以 DRY 和 KISS 方式完成?

如上面评论中所述(有问题)- ,我必须为我需要的每个实体创建存储库。同样值得考虑 aggregate roots (如果某些实体不会被直接查询)。

当我使用包含大约 100 多个实体的数据源时,我使用了以下方法,这样就不会为每个实体创建存储库。 我的工作主要是为了将信息从源头保存到我们的数据库中。但是也知道如何检索数据。

创建@MappedSuper的主要思路class:

@MappedSuperclass
public abstract class SuperClass {

    @Id
    @GeneratedValue
    private Integer id;

    public SuperClass() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

然后扩展所有其他实体:

@Entity
public class Class1 extends SuperClass {

    private String classInfo;

    public String getClassInfo() {
        return classInfo;
    }

    public void setClassInfo(String classInfo) {
        this.classInfo = classInfo;
    }

    @Override
    public String toString() {
        return "\nClass1{" +
                "classInfo='" + classInfo + '\'' +
                '}';
    }
}

@Entity
public class Class2 extends SuperClass {

    private String classInfo;

    public String getClassInfo() {
        return classInfo;
    }

    public void setClassInfo(String classInfo) {
        this.classInfo = classInfo;
    }

    @Override
    public String toString() {
        return "\nClass2{" +
                "classInfo='" + classInfo + '\'' +
                '}';
    }
}

在这种情况下,您的存储库将是:

public interface SuperRepository extends JpaRepository<SuperClass, Integer> {

}

你可以应用它:

    Class1 class1 = new Class1();
    class1.setClassInfo("Class1 info");

    Class2 class2 = new Class2();
    class2.setClassInfo("Class2 info");

    superRepository.save(class1);
    superRepository.save(class2);

    //OR 
    //List<SuperClass> entities = Arrays.asList(class1,class2);
    //superRepository.saveAll(entities);

Hibernate 将创建 Class1Class2 表并用数据填充它们。

下一步 - 如何检索数据。 我会考虑这样的方法——为这个存储库中的每个 class 创建查询:

public interface SuperRepository extends JpaRepository<SuperClass, Integer> {

    @Query("select c from Class1 c")
    List<Class1> findAllClass1();

    @Query("select c from Class2 c")
    List<Class2> findAllClass2();

}

然后当你应用这个时:

    System.out.println(superRepository.findAllClass1());
    System.out.println(superRepository.findAllClass2());

您将获得:

[Class1{classInfo='Class1 info'}]

[Class2{classInfo='Class2 info'}]

对于登陆此处寻找避免存储库接口文件过多的方法的人。从 5.0 开始,Spring 中有一个叫做 'Composable Repositories' 的东西,并且有相当多的示例代码可用,所以我不打算在这里重新解释。 我发现了一种类似的方法来避免太多文件,如下所示: 创建一个普通的 class 成为所有这些空存储库接口的供应商。将 @Repository 接口定义为包含 class 的非 public 接口,并为每个存储库编写 getter。示例如下:

Public MyRepositoryProvider {

  @Autowired 
  Class1Repository class1Repo;
  public Class1Repository getClass1Repo() {
      return class1Repo;

  //.... similarly for Class2Repo

}

@Repository
interface Class1Repository extends CRUDRepository<Class1, Long>{}
@Repository
interface Class2Repository extends CRUDRepository<Class2, Long>{}

将所有这些都放在一个 java 文件中。并确保它在您的项目的存储库扫描路径中。