[Spring] JPA + MySQL (M:N, 다대다 관계)
프로젝트 생성
다대일 N:1관계 때 사용한 jpa2 폴더 복사 붙인 후, 폴더명 jpa3
으로 변경
AppTest.java에서 testSave()
만 남겨두기
persistence.xml
에서
1) value = "update"가 아닌 create
로 되어있는지 확인해야함
2) 프로젝트 명 jpa2에서 jpa3로 바꾸기
AppTest.java의 testSave()
에서 Persistence.createEntityManagerFactory("jpa3"
);으로 되어있는지 확인
STUDENT
, MAJOR
TABLE에 DATA가 제대로 추가됐다!
MAJOR에서도 STUDENT가 조회할 수 있도록 설정하기 (객체 지향 코드, 다대다 관계)
객체 지향 코드는 MAJOR에서 STUDENT TABLE 필드가 없어서 조회할 수 없었다.
Major.java 코드 추가
// OneToMany : Major입장에서는 전공 1개당 여러명의 student(Many)가 존재
// OneTomany가 없어도 @JoinColumn으로 인해 SQL문에서는 양쪽 모두 조회가 가능하지만, 객체지향 코드에서는 major에서 student를 조회할 수 없다.
// mappedBy = "major"로 인해 외래키를 설정했다. = 연관 관계를 주입?했다
// N:1에서 N 쪽이 주인이 된다.
@OneToMany(mappedBy = "major")
// Student.java의 Major 'major'필드를 지정. 반대쪽 매핑의 필드 이름을 설정
private List<Student> students = new ArrayList<>();
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
AppTest.java - readStudents()
// JPA를 활용하여 STUDENT LIST 조회하기
@Test
public void readStudents(){
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa3");
EntityManager em = emf.createEntityManager();
// EntityTransaction tx = em.getTransaction(); 조회할 때는 tx 필요 X
Major major = em.find(Major.class, 1L);
List<Student> students = major.getStudents();
for(Student student : students){
System.out.println(student.getStudentName());
}
}
persistence.xml에서 update
로 변경 후 @Test readStudents() 실행
디버그 콘솔에 김나나, 김빵빵 출력됐다.
testSaveNonOwnerWithJPA()
@Test
public void testSaveNonOwnerWithJPA(){
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa3");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Major major1 = new Major("통계학과");
em.persist(major1);
Student student1 = new Student("강우리");
Student student2 = new Student("송진희");
// student1.setMajor(major1); : 원래는 이렇게 해야하는데
// 연관 관계의 주인은 N : 1 에서 N(Student.java)에 해당한다.
// 🤔 연관 관계의 주인이 아닌 M(Major)에만 연관 관계를 설정할 경우 ???
// 즉, student1.setMajor(major1); 를 설정하지 않은상태
major1.getStudents().add(student1); // 🤔?
major1.getStudents().add(student2); // 🤔?
em.persist(student1);
em.persist(student2);
tx.commit();
}
create
로 변경
실행은 제대로 됐지만,
MAJOR_ID가 NULL
이 들어갔다!!
testSaveOwnerOnlyWithOOP() - 객체지향 코드로 연관 관계의 주인(Student)에만 연관 관계를 설정한 경우
즉, major1.getStudents().add(student1);
코드가 없음!!
@Test
public void testSaveOwnerOnlyWithOOP(){
// OOP = 순수한 객체 지향 코드로만 설정
Major major1 = new Major("통계학과");
Student student1 = new Student("강우리");
student1.setMajor(major1);
// major1.getStudents().add(student1); 코드가 없음!!
Student student2 = new Student("송진희");
student2.setMajor(major1);
List<Student> students = major1.getStudents();
System.out.println("students.size : " + students.size());
}
size : 0
이 출력된다 !!! (오류인 상황)
biWithOOP() - 순수 객체 지향 코드에서 양방향 맵핑 적용한 경우
@Test
public void biWithOOP(){ // 순수 객체 지향적인 양방향 맵핑 적용 결과
// 학과
Major major1 = new Major("수학과");
Student student1 = new Student("강우리");
Student student2 = new Student("송진희");
student1.setMajor(major1); // 연관관계 주인 맵핑
student2.setMajor(major1);
major1.getStudents().add(student1); // 반대편 연관 관계 팹핑
major1.getStudents().add(student2);
List<Student> students = major1.getStudents();
System.out.println("student.size : " + students.size()); // 2
}
size : 2
로 정확하게 출력됐다!
biWithJPA() - JPA를 적용한 양방향 맵핑
@Test
public void biWithJPA(){
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa3");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Major major1 = new Major("수학과");
em.persist(major1);
Student student1 = new Student("강우리");
Student student2 = new Student("송진희");
// 양방향 연관 관계 설정하기
student1.setMajor(major1); // 연관관계 주인 맵핑
student2.setMajor(major1);
major1.getStudents().add(student1); // 반대편 연관 관계 팹핑
major1.getStudents().add(student2);
// 영속성 컨텍스트에 영속화
em.persist(student1);
em.persist(student2);
// 확인을 위해 JOIN문을 사용해야한다던데..
// SELECT S.*, M.MAJOR_FILED FROM STUDENT S JOIN MAJOR M ON S.MAJOR_ID = M.MAJOR_ID WHERE S.MAJOR_ID = 1;
tx.commit();
}
JOIN문 사용하여 MAJOR_FIELD를 확인할 수 있다.
SELECT S.*, M.MAJOR_FILED FROM STUDENT S JOIN MAJOR M ON S.MAJOR_ID = M.MAJOR_ID WHERE S.MAJOR_ID = 1;
Author And Source
이 문제에 관하여([Spring] JPA + MySQL (M:N, 다대다 관계)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dingdoooo/Spring-JPA-MySQL-MN-다대다-관계저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)