본문 바로가기
SPRING

[JAVA] JPA 연관관계 매핑

by 킹명주 2022. 7. 25.

https://mjoo1106.tistory.com/entry/JAVA-JPA-%EC%8B%A4%EC%8A%B5Create-table-and-PKFK-%EC%84%A4%EC%A0%95

 

[JAVA] JPA 실습(Create table and PK/FK 설정)

https://mjoo1106.tistory.com/entry/JAVA-JPA-%EA%B0%9C%EB%85%90-%EB%B0%8F-%EC%98%88%EC%A0%9C [JAVA] JPA 개념 및 예제 저번에 spring에서 jpa를 활용하여 로그인 및 회원가입을 구현했다. 근데 jpa를 잘 모르..

mjoo1106.tistory.com

 

앞서 실습시간에 만들었던 예제를 바탕으로 이번에는 연관관계 매핑을 할 예정이다.

현재 테이블에서는 다대다 관계는 없고 일대 다 관계만 존재한다.

STUDENT와 ENROLL의 경우 1 대 다의 관계를 가지고 SUBJECT와 ENROLL 또한 1 대 다의 관계를 가진다. 이를 참고하여 새롭게 객체스럽게 JPA를 설계해보고자 한다.


테이블 설계

 

앞서 설계한 ENROLL CLASS만 수정하면 된다. 기존 코드를 살펴보고 이를 수정해보자

1. 수정 전

package jpaenroll.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.time.LocalDateTime;

@Entity
public class Enroll {
    @Id @GeneratedValue
    @Column(name="enrollment_id")
    private Long id;
    @Column(name="student_id")
    private Long studentid;
    @Column(name="subject_id")
    private Long subjectid;
    private LocalDateTime enrolldate;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getStudentid() {
        return studentid;
    }

    public void setStudentid(Long studentid) {
        this.studentid = studentid;
    }

    public Long getSubjectid() {
        return subjectid;
    }

    public void setSubjectid(Long subjectid) {
        this.subjectid = subjectid;
    }

    public LocalDateTime getEnrolldate() {
        return enrolldate;
    }

    public void setEnrolldate(LocalDateTime enrolldate) {
        this.enrolldate = enrolldate;
    }
}

이 경우 FK를 직접 매핑한 케이스다. 이 때 수동으로 전부 연결시킬 수 있지만 이는 객체를 활용하는 방향과는 벗어난다. 또한, studentid, subject_id가 null 값이 들어가는 경우도 빈번하다. 그래서 이를 아래와 같이 수정했다.

 

2. 수정 후

package jpaenroll.domain;

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
public class Enroll {
    @Id @GeneratedValue
    @Column(name="enrollment_id")
    private Long id;
    @ManyToOne
    @JoinColumn(name="student_id")
    private Student student;
    @ManyToOne
    @JoinColumn(name="subject_id")
    private Subject subject;

    private LocalDateTime enrolldate;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    public Subject getSubject() {
        return subject;
    }

    public void setSubject(Subject subject) {
        this.subject = subject;
    }

    public LocalDateTime getEnrolldate() {
        return enrolldate;
    }

    public void setEnrolldate(LocalDateTime enrolldate) {
        this.enrolldate = enrolldate;
    }
}

 

3. JOIN 

Q. 첫 번째로 수강신청에 성공한 과목의 이름은?

앞 시간에 만들었던 JpaMain의 try문을 수정해주자.

        try {
            // 첫 번째로 수강신청한 과목의 이름은 무엇인가?
            Enroll enroll=em.find(Enroll.class, 1L);
            System.out.println(enroll.getSubject().getName());
            tx.commit();
        }

성공적으로 과목명을 조회했다. 앞서 사용했던 방식보다 훨씬 간단하고, 이러한 형태가 객체를 타고 타는 형태이므로 객체 지향에 더 가깝다고 볼 수 있다. 

조회는 정말 쉽게 끝났고 그 다음으로는 테이블 삽입 문제이다.

 

Q. 학번이 160165, 5학년, 전공이 수학인 학생이 JPA_BASIC 수업을 수강신청 했다. 이 때 student, enroll table에 추가하시오.

  try {
            // student id가 160165이고 4학, 전공이 수학인 사람을 추가하고
            // 이 사람이 JPA_BASIC 과목을 추가한다한다면?
            Student student = new Student();
            student.setId(160165L);
            student.setGrade(5);
            student.setMajor(KindOfMajor.Math);
            em.persist(student);

            Enroll enroll = new Enroll();
            enroll.setStudent(student);
            enroll.setEnrolldate(LocalDateTime.now());
            enroll.setSubject(em.find(Subject.class, 1101L));
            em.persist(enroll);

            tx.commit();
        }

성공적으로 insert 한 것을 살펴볼 수 있다.


이번에 진행한 내용은 단방향만 다루었다. 양방향으로 더 코드를 간단하게 할 수 있지만 이는 선택사항이다. 왜냐하면 어차피 단방향으로도 모든 것을 다룰 수 있다. 그러므로 관계 매핑에서 단방향 설계를 잘하는 것이 가장 중요하다.

'SPRING' 카테고리의 다른 글

[Spring] JPA CASCADE  (2) 2022.08.31
[Spring] JWT 실습 - 1  (2) 2022.07.27
[JAVA] JPA 실습(Create table and PK/FK 설정)  (0) 2022.07.19
[JAVA] JPA 개념 및 예제  (0) 2022.07.18
[Spring] JPA를 활용한 로그인 구현  (2) 2022.07.15