[Spring] JPA + MySQL (N:1, 다대일 관계)

진주·2022년 3월 22일
0

Spring

목록 보기
24/29
post-thumbnail

3) 🥩 AppTest.java - JPA 사용해보기(Save😎)


  @Test
  public void testSave(){
      EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa2");
      EntityManager em = emf.createEntityManager();
      EntityTransaction tx = em.getTransaction();
      
      tx.begin();

      // 학과 데이터 저장
      Major major1 = new Major("컴퓨터 공학");
      // 영속성 컨텍스트에 저장
      em.persist(major1); 
      
      // 학생1 데이터 저장, JPA가 자동으로 AUTO_INCREMENT 해준다.
      Student student1 = new Student("Yoon");
      Student student2 = new Student("Kang");
      
      // student1의 major를 "컴퓨터 공학"으로 정해준다.       
      student1.setMajor(major1);

      // 영속성 컨텍스트에 저장
      em.persist(student1);
      em.persist(student2);

      // DB에 data 저장
      tx.commit();

  }
}

JPA가 id 값을 AUTO_INCREMENT를 자동으로 만들어주기 때문에,

// Major.java에 존재
  public Major(Long id, String majorName) {
    Id = id;
    this.majorName = majorName;
  }
  
// Student.java에 존재  
    public Student(Long id, String studentName) {
    Id = id;
    this.studentName = studentName;
  }
  

위 코드의 생성자를 사용하지 않는다.


대신 id 값을 직접 넣어줄 필요 없는

Major major1 = new Major("컴퓨터 공학");
Student student1 = new Student("Yoon"); 를 사용한다.

현재 Student, Major 클래스에는 생성자가 존재하지 않으니 추가해준다.

// Student.java에 추가
  public Student(String studentName) {
    this.studentName = studentName;
  }
  
// Major.java에 추가 
  public Major(String majorName) {
    this.majorName = majorName;

  }

생성자를 각각 Student.javaMajor.java에 추가해줘야한다.

[결과]

변경되었음을 확인할 수 있다 😎


issue !

원래 오류가 났었는데, https://lowell-dev.tistory.com/4 를 참고해서
ddl.sql에 아래 코드를 추가해줬었다.

ALTER TABLE STUDENT CONVERT TO CHARSET utf8;
ALTER TABLE MAJOR CONVERT TO CHARSET utf8;

근데 에러 해결이 이것 때문에 된 것인지는 모르겠지만... 알아두자!


4) AppTest.java - JPA 사용해보기(Read😊)

    @Test
    public void testRead(){
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa2");
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();

		tx.begin();
        
        // Join되는 부분, Student 테이블에서 Id가 1인 학생을 찾아온다.
        Student student = em.find(Student.class, 1L);
        
        // Major Entity가 들어가있음
        Major major = student.getMajor();
        System.out.println("전공 이름 : " + major.getMajorName());

        tx.commit();
    }

Student.java에서 major를 외래키로 설정해줬기 때문에,
student.getMajor()를 통해 MAJOR_ID에 접근할 수 있다.


코드 추가하고 실행하면 오류발생 !!

오류 나는 이유는, persistence.xml의

<property name="hibernate.hbm2ddl.auto" value="create"/> 코드 때문에 TABLE을 DROP + CREATE 하기 때문이다.

@Test Read를 할 때는 TABLE을 DROP하지 않기 위해서 value="update" 로 변경한다.

다시 AppTest.java 실행하면 정상적으로 실행되고,

디버그 콘솔에 전공 이름 : 컴퓨터 공학 이 출력된다!! 🤗


5) AppTest.java - JPA 사용해보기(Update😮)

  1. 새로운 major 국문학과 생성, 영속화(persist)
  2. 학생1(1L) 조회 후(find), 새로운 학과(국문학과)로 설정

    @Test
    public void updateRelation() {

        EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa2");
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        Major major2 = new Major("국문학과");
        em.persist(major2);
        
        // 학생 1 (1L) 조회, em.find() = findById와 비슷함
        Student student = em.find(Student.class,1L); 
        // em.update() 같은 별도의 메서드가 없고, set메서드를 활용하여 이전 Entity 비교하여 변경된 부분이있으면 update한다.
        student.setMajor(major2);
        System.out.println(student.getMajor().getMajorName());
        
        // flush()가 내부적으로 호출되어, DB의 데이터를 변경시킨다.
        tx.commit();
    }

1) Major major = new Major("국문학과") 를 통해 Major_ID가 2번인 "국문학과"가 생성되었다.

2) student.setMajor(major2) 를 통해 student Id가 1번인 Yoon의 major가 2번(=국문학과)으로 변경되었다.


6) AppTest.java - JPA 사용해보기(DeleteRelation😧)

학생 1의 전공 제거하기

    @Test
    public void deleteRelation() { // 연관관계 제거
        /**
         * 1. 학생1의 전공을 제거(null)
         */
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa2");
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        Student student1 = em.find(Student.class, 1L);
        student1.setMajor(null);    // 국문학과에서 null값으로

        tx.commit();
    }

student1인 Yoon의 major가 null값으로 변경되었다!!
student1과 major의 관계가 끊어진 것!


7) AppTest.java - JPA 사용해보기(deleteEntity😭)

  1. 컴퓨터 공학 전공 Entity를 DB에서 제거

    @Test
    public void deleteEntity() { // Entity 제거
        /**
         * 1. 컴퓨터 공학 전공 Entity를 DB에서 제거
         */
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa2");
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        Major major1 = em.find(Major.class,1L);
        em.remove(major1); // remove 자체가 em.persist() 처럼 동작
        
        tx.commit();
    }

MAJOR_ID 1번인 "컴퓨터 공학"이 삭제되었다!


ISSUE

원칙적으로는 MAJOR_ID 1번인 컴퓨터 공학을 삭제하기 전에,
Student Table에서 컴퓨터 공학에 해당하는 학생의 major값을 null로 설정해야한다.


궁금증...

컴퓨터 공학이 Student가 여러명이면 어떻게해야하는거징 , ,?

profile
진주의 코딩일기

0개의 댓글