개발/Spring
Spring - JPA (2) 다중성
로그뉴
2022. 7. 12. 13:37
연관관계의 대칭성
- 일대다 ↔ 다대일
- 일대일 ↔ 일대일
- 다대다 ↔ 다대다
다대일(N:1) - @ManyToOne
ex) 게시판(Board)과 게시글(Post)의 관계
- 요구 사항
- 하나의 게시판(1)에는 여러 게시글(N)을 작성할 수 있다.
- 하나의 게시글은 하나의 게시판에만 작성할 수 있다.
- 게시글과 게시판은 다대일 관계를 갖는다.
데이터베이스를 기준으로 다중성(게시글N : 게시판1)을 결정. 즉, 외래 키를 게시글(N)이 관리하는 일반적인 형태이다.
참고) 데이터베이스는 무조건 다(N)쪽이 외래 키를 갖는다.
- 단방향
- Post(N) 객체에 Board(1) 객체 선언 후, @ManyToOne 어노테이션 추가.
- Board 객체에서는 참조하지 않음.
-
12345678910@Entitypublic class Post {@Id@GeneratedValueprivate Long id;@ManyToOne@JoinColumn(name = "BOARD_ID")private Board board;}
- 양방향
- Board(1) 객체에 Post(N) 객체 선언 후, @OneToMany 어노테이션 추가.
- 연관관계 주인: Post(N), mappedBy 사용.
-
123456789@Entitypublic class Board {@Id@GeneratedValueprivate Long id;@OneToMany(mappedBy = "board")List<Post> posts = new ArrayList<>();}
일대다(1:N) - @OneToMany
데이터베이스 입장에서는 무조건 다(N)쪽에서 외래키를 관리한다. 일대다 관계는 일(1)쪽 객체에서 다(N) 쪽 객체를 조작(생성,수정,삭제)하는 방법.
다대일과의 차이: 일대다의 기준은 연관관계의 주인을 일(1)쪽에 둔 것.
- 단방향
- Board(1) 객체에 Post(N) 객체 선언 후, @OneToMany 어노테이션 추가.
- @JoinColumn 사용한 조인.
-
12345678910@Entitypublic class Board {@Id@GeneratedValueprivate Long id;@OneToMany@JoinColumn(name = "POST_ID")List<Post> posts = new ArrayList<>();}
- 양방향
- 연관관계 주인: Board(1)
참고) 실무에서는 일대다(1:N) 단방향은 거의 쓰지 않음.
만약, 일대다(1:N) 양방향을 사용해야 한다면 다대일(N:1) 양방향 사용을 하도록 하자.
일대일(1:1)
주 테이블에 외래키를 넣을 수도 있고, 대상 테이블에 외래키를 넣을 수도 있다.
참고) 일대일(1:1)이기 때문에 테이블 A, B가 있을 때, A가 주 테이블이면 B가 대상 테이블이고, B가 주 테이블이면 A가 대상 테이블이 된다.
- 단방향
- Post 객체에 PostSub 객체 선언 후, @OneToOne 어노테이션 추가. (PostSub는 Post와 1:1로 매핑된 관계.)
- 양방향
- 연관관계 주인: 외래키가 있는 곳.
다대다(N:N)
참고) 실무에서는 사용하지 않음.
중간 테이블이 숨겨져 있기 때문에 자기도 모르는 복잡한 조인의 쿼리(Query)가 발생하는 경우가 생길 수 있기 때문.
다대다로 자동생성된 중간테이블은 두 객체의 테이블의 외래 키만 저장되기 때문에 문제가 될 확률이 높습니다. JPA를 해보면 중간 테이블에 외래 키 외에 다른 정보가 들어가는 경우가 많기 때문에 다대다를 일대다, 다대일로 풀어서 만드는 것(중간 테이블을 Entity로 만드는 것)이 추후 변경에도 유연하게 대처할 수 있다.