항해99 Day31 [JPA 연관관계]

Colleen·2023년 2월 19일
0
post-thumbnail

JPA에서 가장 중요한 건?

객체와 관계형 데이터베이스 테이블이 어떻게 매핑되는지 이해하는 것이다.

왜?

객체지향 프로그래밍과 데이터베이스 사이의 패러다임 불일치를 해결하는 것이 JPA의 목적과 직접적으로 연관되어 있기 때문이다.

여기서 잠깐!! 패러다임 불일치란?

객체 지향 프로그래밍과 관계형 데이터베이스 사이의 데이터 표현 방식이 달라서 생겨나는 문제이다.

즉, 객체지향에서는 추상화, 상속, 다형성 같은 개념이 있지만, 데이터베이스에서는 추상화, 상속, 다형성 같은 개념들이 없기 때문에 서로가 지향하는 목적이 다르므로 패러다임 불일치 문제라고 한다.

연관 관계를 매핑할 때 생각해야 할 것

  • 방향 : 단반향, 양반향
  • 다중성 : 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M)
  • 연관 관계의 주인 : 양방향일 때 연관 관계에서 관리 주체

방향(단방향과 양방향)

객체는 참조용 필드가 있는 객체만 다른 객체를 참조하는 것이 가능하다.

때문에, 두 객체 사이에 하나의 객체만 참조용 필드를 가지고 참고하게 되면 단방향 관계이고,

두 객체 모두가 각각 참조형 필드를 가지고 참조하면 양방향 관계이다.

JPA를 사용하여 패러다임을 맞춰주기 위해서 객체는 단방향 연관 관계를 가질지, 양방향 연관 관계를 가질지 선택해줘야 한다.

연관 관계의 주인

두 객체가 연관 관계를 맺으면 연관 관계의 주인을 정해야 하는데,

두 단반향 관계 중에서 제어의 권한을 갖는 실질적인 관계가 어떤 것인지 JPA에게 알려주는 것이다.

외래 키가 있는 곳이 연관 관계의 주인이다!

다중성

다중성은 데이터베이스를 기준으로 결정하며 연관관계는 대칭성을 가진다.

- 다대일(N:1) :

  • 하나의 게시판에 여러 개의 게시글을 작성할 수 있다
  • 하나의 게시글은 하나의 게시판에만 작성할 수 있다
  • 이럴 때 게시글과 게시판은 다대일 관계를 갖는다.

@Entity
public class Member {

    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    
    private String username;
    
    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;
    
    ...
}
@Entity
public class Team {
	
    @Id @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;
    
    private String name;
    
    ...

}

- 일대다(1:N)

  • 다대일에 경우에는 연관관계의 주인을 다(N)쪽에 둔 것이라면
    일대다에 경우에는 연관관계의 주인이 일(1)쪽에 둔 것이다.
  • 나는 취미가 여러개다. 즉, 나와 취미는 1 : N 관계이다.

@Entity
public class Member {

    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    
    private String username;
    
    ...
}
@Entity
public class Team {
	
    @Id @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;
    
    private String name;
    
    @OneToMany
    @JoinColumn(name = "TEAM_ID")
    private List<Member> members = new ArrayList<>();
    
    ...

}

- 일대일(1:1)

  • 주 테이블에 외래키를 넣거나 대상 테이블에 외래키를 넣는
    것이 모두 가능하다.
  • 즉, A, B 라는 테이블이 각각 존재한다고 했을 때
    A가 주 테이블일 때 B가 대상 테이블,
    B가 주 테이블일 때 A가 대상 테이블이다.
  • 나와 내 신체정보는 1:1로 매칭된다.
@Entity
public class Member {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "MEMBER_ID")
    private Long id;
    
    private String username;
    
    
    @OneToOne
    @JoinColumn(name = "LOCKER_ID")
    private Locker locker;
}
@Entity
public class Locker {

    @Id @GeneratedValue
    @Column(name = "LOCKER_ID")
    private Long id;

    private String name;
}

다대다(N:M)

  • 안쓰는 게 가장 좋다고 한다. / 쓰지 않는 걸로

다대다 관계 대신 연결 엔티티를 사용한다.

두 테이블을 연결하는 연결 테이블을 만들고, 그것을 연결 엔티티로 승격시켜줍니다.

즉 @ManyToMany -> @OneToMany와 @ManyToOne으로 나눠지는 것입니다.

https://blog.kakaocdn.net/dn/5kQYq/btrnQ7cCZsK/FCPjCpykwNNaEAxBSwZcY0/img.png

Member와 Product의 다대다 관계를 Order 엔티티를 추가하며 1대다, 다대1 관계로 풀어냄

profile
이상한 나라의 개발하는 예대생

0개의 댓글