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 将创建 Class1 和 Class2 表并用数据填充它们。
下一步 - 如何检索数据。
我会考虑这样的方法——为这个存储库中的每个 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 文件中。并确保它在您的项目的存储库扫描路径中。
在我当前的项目中,我正在使用 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 将创建 Class1 和 Class2 表并用数据填充它们。
下一步 - 如何检索数据。 我会考虑这样的方法——为这个存储库中的每个 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 文件中。并确保它在您的项目的存储库扫描路径中。