我想用Spring Data JDBC建模一个OneToMany关系。我在这个非常有用的博客https://spring.io/blog/2018/09/24/spring-data-jdbc-references-and-aggregates上读到,当您想对ToMany引用建模时,应该使用引用:
因此,任何多对一和多对多关系都必须仅通过引用ID来建模。
@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<>();
}
你引用的是“多对多”的文章,但你自己也在谈论“X对多”。您可以使用直接引用或实体列表/集合/映射来建模一对一或一对多关系。
你应该避免的是双向关系。虽然您可能可以用您正在使用的方法使它们工作,但您真的不应该这样做。
这就给我们带来了一个问题:这个模型应该是什么样子的?
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可以操作简单的属性。
如果registration
和student
都是聚合,那么就会涉及到更多的问题:您需要决定哪一方拥有引用。
第一种情况:注册
拥有引用。
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;
}
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
列。