Попробуйте извлечь данные пользовательских объектов из базы данных с помощью spring data jpa из нескольких таблиц

#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;
}
   
 
  1. Вы можете Использовать Набор Вместо Списка.
  2. Всегда используйте Сопоставление на одной стороне, если вы используете его на одной стороне, это создаст дополнительную таблицу.
  3. Вы можете использовать тип выборки нетерпеливый или ленивый. По умолчанию он ленивый, и вы должны использовать @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;
}
 

Обратите внимание на все изменения, которые я здесь внес.

  1. Для данных, сохраненных в базе данных, Long это лучший выбор, чем int . Аналогично, например, используйте Boolean вместо boolean .
  2. Думайте об Student этом как о стороне, управляющей отношениями «многие ко многим», и Course как о целевой стороне. На целевой стороне используйте @JsonIgnore и @ToString.Exclude аннотации, чтобы избежать бесконечной рекурсии, стекового потока или OOM.
     @JsonIgnore
    @EqualsAndHashCode.Exclude
    @ToString.Exclude
    @ManyToMany(mappedBy = "courses",fetch = FetchType.EAGER,cascade = CascadeType.ALL)
 
  1. Используйте Set вместо List , если студент не должен выбирать точно такой же курс. Это гарантирует , что вы все еще можете выбрать 2017 fall Maths и 2018 fall Maths , в то время как вы не можете выбрать 2017 fall Maths дважды.