#java #spring #spring-boot #hibernate #spring-data-jpa
Вопрос:
Я хочу получить данные из нескольких таблиц.
public class Student{
private int id;
private String name;
private List<Course> course;
}
public class Course{
private int id;
private String name;
private int studentId;
}
Я хочу получить данные из таблицы студентов и курсов с помощью spring data jpa и сопоставить их с объектом student.
Как я могу сделать это эффективным способом?
Комментарии:
1. Вот базовый учебник Spring JPA, который должен пригодиться. Если у вас есть более конкретные вопросы, обновите вопрос. spring.io/guides/gs/accessing-data-jpa
Ответ №1:
@Data
@NoArgsConstructor
public class Student{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String name;
@OneToMany(mappedBy="studentId",cascade=CascadeType.ALL,fetch=FetchType.Eager)
private Set<Course> course;
}
- Вы можете Использовать Набор Вместо Списка.
- Всегда используйте Сопоставление на одной стороне, если вы используете его на одной стороне, это создаст дополнительную таблицу.
- Вы можете использовать тип выборки нетерпеливый или ленивый. По умолчанию он ленивый, и вы должны использовать @transactional ленивого.
@Data @NoArgsConstructor public class Course{ @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; private String name; @ManyToOne @JoinColumn(name="studentId") private int studentId; }
Надеюсь, этот ответ Решит ваш запрос Счастливого кодирования!.
Ответ №2:
Обратите внимание, что отправная точка может быть неправильной. Я предполагаю, что студент может выбрать несколько курсов, и курс может быть выбран несколькими студентами. Так что на самом деле @ManyToMany
это отношения, но не @ManyToOne
или @OneToMany
.
Вам определенно понадобится совместная таблица для сопоставления их первичных ключей из двух таблиц в общую таблицу.
@Entity
@Data
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@EqualsAndHashCode.Exclude
@ManyToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
@JoinTable(
name = "courses",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id"))
private Set<Course> courses;
}
@Entity
@Data
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@JsonIgnore
@EqualsAndHashCode.Exclude
@ToString.Exclude
@ManyToMany(mappedBy = "courses",fetch = FetchType.EAGER,cascade = CascadeType.ALL)
private Set<Student> students;
}
Обратите внимание на все изменения, которые я здесь внес.
- Для данных, сохраненных в базе данных,
Long
это лучший выбор, чемint
. Аналогично, например, используйтеBoolean
вместоboolean
. - Думайте об
Student
этом как о стороне, управляющей отношениями «многие ко многим», иCourse
как о целевой стороне. На целевой стороне используйте@JsonIgnore
и@ToString.Exclude
аннотации, чтобы избежать бесконечной рекурсии, стекового потока или OOM.
@JsonIgnore
@EqualsAndHashCode.Exclude
@ToString.Exclude
@ManyToMany(mappedBy = "courses",fetch = FetchType.EAGER,cascade = CascadeType.ALL)
- Используйте
Set
вместоList
, если студент не должен выбирать точно такой же курс. Это гарантирует , что вы все еще можете выбрать2017 fall Maths
и2018 fall Maths
, в то время как вы не можете выбрать2017 fall Maths
дважды.