gpt4 book ai didi

java - OneToMany Spring Data JDBC

转载 作者:搜寻专家 更新时间:2023-11-01 01:59:37 24 4
gpt4 key购买 nike

我想使用 Spring Data JDBC 为 OneToMany 关系建模。我读过这个非常有用的博客 https://spring.io/blog/2018/09/24/spring-data-jdbc-references-and-aggregates当你想对 ToMany 引用进行建模时,你应该使用引用:

Therefore any Many-to-One and Many-to-Many relationship must be modeled by just referencing the id.

所以我有这个场景:
一个 Student 可以有多个 Registration。并且一个 Registration 可以恰好有一个 Student。如果您删除 Registration,分配的 Student 不应被级联删除。
我最终得到了这个模型:

@Data
@AllArgsConstructor(access = AccessLevel.PRIVATE, onConstructor = @__(@PersistenceConstructor))
public class Registration {

private final @Id
@Wither
long registrationId;

@NotNull
private String electiveType;

@NotNull
private LocalDateTime created = LocalDateTime.now();

@NotNull
private StudentRegistrationReference studentRegistrationReference;

}

@Data
@AllArgsConstructor(access = AccessLevel.PRIVATE, onConstructor = @__(@PersistenceConstructor))
public class StudentRegistrationReference {
private long student;
private long registration;
}

@Data
@AllArgsConstructor(access = AccessLevel.PRIVATE, onConstructor = @__(@PersistenceConstructor))
public class Student {

private final @Id
@Wither
long studentId;

@NotNull
@Size(min = 4, max = 20)
private String userId;

@NotNull
@Min(0)
private int matriculationNumber;

@NotNull
@Email
private String eMail;

private Set<StudentRegistrationReference> studentRegistrationReferences = new HashSet<>();

}

我的问题是我的建模是否正确实现?

最佳答案

您引用的是关于“多对多”的文章,但您自己却在谈论“多对多”。您可以使用直接引用或实体的列表/集合/映射来建模一对一或一对多关系。

您应该避免的是双向关系。虽然您可能可以让它们按照您正在使用的方法工作,但实际上不应该这样做。

这让我们想到了一个问题:这个模型应该是什么样子?

要做出的核心决定是涉及多少聚合?

Student 肯定是一个聚合,Student 类是它的聚合根。它可以独立存在。

但是注册呢?我会争辩说,它可能是同一聚合的一部分。删除测试是一个很好的测试。如果你从系统中删除了一个Student,那个Student的注册还有值(value)吗?还是应该与 Student 一起消失?

作为练习,我们来做这两种变体。我开始于:只有一个聚合:

class Registration {

@Id private long Id;

String electiveType;
LocalDateTime created = LocalDateTime.now();
}

class Student {

@Id private long Id;

String userId;
int matriculationNumber;
String eMail;
Set<Registration> registrations = new HashSet<>();
}

这样,您将拥有一个存储库:

interface StudentRepository extends CrudRepository<Student, Long>{}

我删除了所有 Lombok 注释,因为它们与问题无关。 Spring Data JDBC 可以对简单的属性进行操作。

如果 RegistrationStudent 都是聚合,它会涉及更多:您需要决定哪一方拥有引用。

第一种情况:Registration 拥有引用。

class Registration {

@Id private long Id;

String electiveType;
LocalDateTime created = LocalDateTime.now();

Long studentId;
}

public class Student {

@Id private long Id;

String userId;
int matriculationNumber;
String eMail;
}

第二种情况:Student 拥有引用

class Registration {

@Id private long Id;

String electiveType;
LocalDateTime created = LocalDateTime.now();
}

class Student {

@Id private long Id;

String userId;
int matriculationNumber;
String eMail;

Set<RegistrationRef> registrations = new HashSet<>();
}

class RegistrationRef {

Long registrationId;
}

请注意 RegistrationRef 没有 studentId 或类似的。 registrations 属性假定的表将有一个 student_id 列。

关于java - OneToMany Spring Data JDBC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53376101/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com