The Origin:Peer Group:Study03(JPA)

xddongx-hyeon2·2022년 3월 11일
0

spring_boot

목록 보기
10/11

JPA 연관관계 매핑 기초(단방향/양방향)

객체연관관계와 테이블 연관관계를 매핑할 때 고려해야할 3가지

1. 방향(Direction)

  • 단방향, 양방향
  • 게시글, 게시판 관계가 있을 때
    • 게시글 -> 게시판 또는 게시판 -> 게시글 둘 중 한 쪽만 참조한다면 단방향 관계
    • 게시글 -> 게시판, 게시판 -> 게시글 양쪽 모두 서로 참조하는 것은 양방향 관계
  • 방향은 객체 관계에만 존재하고, 테이블은 항상 양바향

2. 다중성(Multiplicity)

  • 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M)
  • 게시글, 게시판 관계가 있을 때
    • 여러 게시글은 한 게시판에 속하므로 게시글:게시판 = N:1
    • 한 게시판에 여러 게시글에 속하믄로 게시판:게시글 = 1:N

3. 연관관계의 주인(owner)

  • 객체를 양방향 연관관계로 만들면 연관관계의 주인을 정해야한다.

단방향 연관관계

객체 연관관계와 테이블 연관관계의 가장 큰 차이

참조를 통한 연관관계는 언제나 단방향. 객체간에 연관관계를 양방향으로 만들고 싶으면 반대쪽에도 필드를 추가 해서 참조를 보관해야한다. 결국 연관관계를 하나 더 만들어야한다. 하지만 이것은 엄밀히 말하면 양방향 관계가 아니라 서로 다른 단방향 관계 2개이다. 반면에 테이블은 외래키 하나로 양방향으로 조인할 수 있다.

단방향 관계(A -> B)

class A {
	B b;
}

class B{}

양방향 관계(A <-> B)

class A {
	B b;
}

class B {
	A a;
}

객체 연관관계 VS 테이블 연관관계 정리

  • 객체는 참조(주소)로 연관관계를 맺는다.
  • 테이블은 외래키로 연관관계를 맺는다.
  • 참조를 사용하는 객체의 연관관계는 단방향이다.
    • A -> B (a,b)
  • 외래 키를 사용하는 테이블의 연관관계는 양방향이다.
    • A JOIN B, B JOIN A 둘 다 가능하며 결과 값도 같다.

객체 관계 매핑하기


테이블 구조가 위와 같을 때, JPA를 사용해서 둘의 관계를 매핑해보자.
게시글 엔티티

@Entity
@Getter
@Setter
public class Post {
	@ID
    @Conumn(name = "POST_ID")
    private Long id;
    
    private Strin username;
    
    // 연관 관계 매핑
    @ManyToOne
    @JoinColumn(name = "BOARD_ID")
}

게시판 엔티티

@Entity
@Getter
@Setter
public class Board {
	@Id
    @Column(name ="BOARD_ID")
    private Long id;
    
    private String name;
}

게시글 엔티티는 게시판 엔티티에 N:1(단방향 관계를 갖는다.)

@JoinColumn

@JoinColumn은 외래키를 매핑할 때 사용한다.

속성기능기본값
name매핑할 외래키 이름"필드명" + _ + 참조하는 테이블의 "기본키 컬럼명"
referencedColumnName외래키가 참조하는 대상 테이블의 컬럼명참조하는 테이블의 "기본키 컬럼명"

참고

@ManyToOne
private Board board;

만약 위과 같이 @JoinColunn을 생략한다면 외래키를 찾을 때 기본전략을 사용한다.

  • 기본전략: 필드명 + _ + 참조하는 테이블의 컬럼명
  • board_BOARD_ID

@ManyToOne

다대일 관계에서 사용한다.

속성기능기본값
optionalflase로 설정하면 연된 엔티티가 항상 있어야한다.true
fetch글로벌 페치 전략@ManyToOne=FetchType.EAGER, @OneToMany=FethchType.LAZY
cascade연속성 전이 기능

양방향 연관관계

게시글에서 게시판으로만 접근하는 단방향 매핑을 알아보았다. 이번엔 게시판에서 게시글로 접근하는 관계를 추가하여 게시글 -> 게시판, 게시판 -> 게시글로 접근할 수 있도록 양방향 연관관계 매핑을 알아보자.

게시판 엔티티

@Entity
@Getter
@Setter
public class Board {
	@Id
    @Column(name ="BOARD_ID")
    private Long id;
    
    private String name;
    
    // 연관관계 추가
    @OneToMany(mappedBy = "board")
    private List<post> postList = new ArrayList<>();
}

mappedBy 속성은 양방향 매핑일 때만 사용하는데, 반대쪽 매핑의 필드값을 주면된다.(Post 클래스의 Board 매핑 필드값인 board)

연관관계의 주인

@OneToMany의 mappedBy는 왜 필요한가?
객체에는 양방향 연관관계라는 것이 없다. 서로 다른 단방향 연관관계 2개를 묶어 양방향인 것처럼 보이게 하는 것이다.(데이터베이스는 외래키 하나로 양방향 연관관계를 맺음)

객체 연관관계

  • 게시글 -> 게시판 연관관계 1개(단방향)
  • 게시판 -> 게시글 연관관계 1개(단방향)

테이블 연관관계

  • 게시판 -> 게시글 연관관계 1개(양방향)

엔티티를 단방향으로 매핑하면 참조를 하나만 사용하므로 이 참조로 외래키를 관리하면된다. 엔티티를 양방향으로 매핑하면 게시글 -> 게시판, 게시판 -> 게시글 두곳에서 서로를 참조한다. 따라서 객체의 연관관계를 관리하는 포인트가 2곳으로 늘어난다. 엔티티를 양방향 연관관계로 설정하면 객체의 참조는 둘인데 외래키는 하나다. 따라서 둘 사이에 차이가 발생한다.(어디서 외래키를 관리해야 하는가?) 이런 차이로 인해 JPA에서는 두 객체 연관관계 중 하나를 정해서 테이블의 외래키를 관리해야하는데 이것을 연관관계의 주인(owner)라고 한다.

양방향 매핑의 규칙: 연관관계의 주인

양방향 매핑 시에는 두 연관관계 중 하나를 연관관계의 주인으로 정해야한다. 연관관계 주인만이 데이터베이스 연관관계와 매핑되고 외리키를 관리(등록, 수정, 삭제)할 수 있다. 주인이 아닌 쪽은 읽기만 할 수 있다.

  • 주인은 mappedBy를 사용하지 않는다.
  • 주인이 아니면 mappedBy를 사용하여 주인을 지정해야한다.

연관관계의 주인은 외래키가 있는곳으로 설정해야한다. 즉 위의 예에서 외래키 board_id를 갖고있는 post테이블 즉, Post엔티티를 주인으로 설정해야한다.

// Board Class
...
public void addPost(Post post) {
	post.setBoard(this);
	postList.add(post);
}
...

참조


https://cornswrold.tistory.com/350

0개의 댓글