SMALL

 

JPA의 연관관계 매핑의 다중성 중에 하나인 One To One Mapping에 관해서 알아보고 예시를 보도록 하자.

언뜻 생각하면 일대일 관계에는 방향성과 관계의 주인이 존재하지 않을 것 같지만,

OneToOne 매핑에서도 방향성과 연관관계의 주인이 존재한다.

 

예시로 학생과 수업 Entity를 살펴보자.

학생은 한 개의 수업만 수강할 수 있고, 수업은 한 명의 학생만 수강할 수 있다.

 

이 관계에서 주인을 학생으로 설정해 보자.

( 연관 관계의 주인은 foreign key를 가지고 있다 )

@Getter
@NoArgsConstructor
@Entity
public class Students {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column
    private String name;
    
    @OneToOne
    private Courses course;

    @Builder
    public Students(String name) {
        this.name = name;
    }

    public void update(String name, Courses course) {
    	this.name = name;
    	this.course = course;
    }
}
@Getter
@NoArgsConstructor
@Entity
public class Courses {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column
    private String name;

}

 

 

주인 테이블에 외래키를 가지고 있는 형태

일대일 관계에서 주인을 설정하는 방법으로는 @OneToOne 어노테이션을 붙여주는 것이다. ( Students )

 

방향 관계

이 상태에서 양방향으로 방향을 지정하고 싶은 경우에는

양방향에 해당하는 Entity에 똑같이 @OneToOne 어노테이션을 붙이고

mappedBy라는 설정을 추가하면 된다. ( Courses )

@Getter
@NoArgsConstructor
@Entity
public class Courses {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column
    private String name;
    
    @OneToOne(mappedBy = "course") // 양방향
    private Students student;
}

 

테스트 코드

위의 관계를 확인하는 테스트 코드를 보자.

    @Test
    public void 코스와학생매핑_oneToone() {
    	String studentName = "jun";
    	String courseName = "meth";
    	
    	Courses course = Courses.builder().name(courseName).build();
    	Students student = Students.builder().name(studentName).build();
    	
    	coursesRepository.save(course);
    	student.update(studentName, course);
    	studentsRepository.save(student);
    	
    	Students ss = studentsRepository.findById(student.getId()).get();
    	assertThat(ss.getCourse().getName().equals(courseName));
    	
    }
LIST
SMALL

JPA를 이용한다면 일반적인 테이블 간의 관계를 이용하는 것처럼, 

Entity 사이의 관계를 통해 데이터를 관리할 수 있다.

 

하지만, JPA를 사용하여 연관관계를 맺기 위해서는 참조 변수를 이용하기 때문에

테이블의 연관과 Entity의 연관이 정확하게 일치하지 않는다.

 

이러한 문제를 해결하면서 연관관계를 매핑하는 방법을 알아야 한다.

 

먼저, 연관관계 매핑에 사용되는 용어들을 정리해 보자.

방향 (Direction)

방향 관계: 두 Entity가 관계를 맺을 때, 한쪽의 Entity만 참조하고 있는 것을 의미한다
방향 관계: 두 Entity가 관계를 맺을 때, 양쪽이 서로 참조하고 있는 것을 의미한다

 

다중성 (Multiplicity)

Many To One: 다대일 (N : 1)
One To Many: 일대다 (1 : N)
One To One: 일대일 (1 : 1)
Many To Many: 다대다 (N : N)

 

위의 관계 중에 일대다(1 : N)와 다대일(N : 1)은 같은 것이라고 생각할 수 있다.

예를 들어, 유저가 게시판에 등록하는 글의 관계를 보면 

유저는 여러개의 글을 등록할 수 있어 : 유저와 게시판의 관계는 일대다(1 : N)

게시판에는 여러 유저가 등록한 글이 존재하므로 : 게시판과 유저의 관계는 다대일(N : 1)

 

어떻게 생각하면 같은 것인데, 중요하게 중점을 두어야 하는 것은

"어떤 Entity를 중심으로 상대 Entity를 바라보느냐" 이다.

 

연관 관계의 주인 (Owner)

Entity 사이의 관계에서의 주인을 찾는 방법은 

연관관계를 갖는 두 테이블에 대해서 외래 키(Foreign Key)를 갖는 테이블이 연관관계의 주인이 된다.

연관관계의 주인만이 외래 키(Foreign Key)를 관리할 수 있고, 반면 주인이 아닌 Entity는 읽기만 할 수 있다.

 

( 결국 Entity의 관계를 생각할 때는 이미 설계된 테이블의 내역을 기반으로 관계를 그리는 게 더 이해하기 쉬운 거 같다)

( 그렇기 때문에 데이터베이스에 대한 지식과 학습이 필요하다고 느껴진다.. ㅎㅎ)

LIST

+ Recent posts