[JPA] 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M) 관계

HAEN·2023년 1월 6일
0

JPA

목록 보기
3/5

다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M) 관계
명칭의 앞에 오는 엔티티가 연관관계의 주인


1. 다대일(1:N) 관계

(1) 다대일 단방향

@Entity
public class Member {
	@Id @GeneratedValue
    @Colum(name = "member_id")
    private Long id;
    
    @ManyToOne // 다대일 연관관계 매핑
    @JoinColum(name = "team_id")
    private Team team;
    
    private String username;
    
}

@Entity
public class Team {
	@Id @GeneratedValue
    @Colum(name = "team_id")
    private Long id;
    
    private String name;
}

(2) 다대일 양방향

외래키가 있는 곳을 연관관계의 주인으로 설정함

@Entity
public class Member {
	@Id @GeneratedValue
    @Colum(name = "member_id")
    private Long id;
    
    @ManyToOne // 다대일 연관관계 매핑
    @JoinColum(name = "team_id")
    private Team team;
    
    private String username;
    
}

@Entity
public class Team {
	@Id @GeneratedValue
    @Colum(name = "team_id")
    private Long id;
    
    @OneToMany(mappedBy = "team") // 양방향 관계에서 연관관계의 주인이 아님을 나타냄
    private List<Member> members = new ArrayList<>();
    
    private String name;
}

2. 일대다(1:N) 관계(권장 X)

(1) 일대다 단방향

@Entity
public class Member {
	@Id @GeneratedValue
    @Colum(name = "member_id")
    private Long id;
    
    private String username;
    
}

@Entity
public class Team {
	@Id @GeneratedValue
    @Colum(name = "team_id")
    private Long id;
    
    @OneToMany
    @JoinColum(name = "team_id")
    private List<Member> members = new ArrayList<>();
    
    private String name;
}
  • 일대다 단방향 매핑의 단점: 엔티티가 관리하는 외래 키가 다른 테이블에 있고, 연관관계 관리를 위해 추가로 UPDATE SQL이 실행됨
    => 일대다 단방향 매핑보다는 다대일 양방향 매핑을 사용

(2) 일대다 양방향

@Entity
public class Member {
	@Id @GeneratedValue
    @Colum(name = "member_id")
    private Long id;
    
    private String username;
    
    @ManyToOne
    @JoinColum(insertable=false, updatable=false) // 읽기 전용 매핑
    private Team team;
    
}

@Entity
public class Team {
	@Id @GeneratedValue
    @Colum(name = "team_id")
    private Long id;
    
    @OneToMany
    @JoinColum(name = "team_id")
    private List<Member> members = new ArrayList<>();
    
    private String name;
}
  • 일대다 양방향 매핑의 단점: 일대다 양방향 매칭은 공식적으로 존재하지 않아 읽기 전용 매핑을 사용해야 함
    => 일대다 양방향 매핑보다는 다대일 양방향 매핑을 사용

3. 일대일(1:1) 관계

(1) 주 테이블에 외래키가 존재하는 일대일 단방향

@Entity
public class Member {
	@Id @GeneratedValue
    @Colum(name = "member_id")
    private Long id;
    
    private String username;
    
    @OneToOne // 일대일 관계 매핑
    @JoinColum(name = "locker_id", unique = true) // unnique 필드 추가
    private Locker locker;
    
}

@Entity
public class Locker {
	@Id @GeneratedValue
    @Colum(name = "locker_id")
    private Long id;
    
    private String name;
}

(2) 주 테이블에 외래키가 존재하는 일대일 양방향

다대일 양방향 관계처럼 외래키가 있는 곳을 연관관계의 주인으로 설정함

@Entity
public class Member {
	@Id @GeneratedValue
    @Colum(name = "member_id")
    private Long id;
    
    private String username;
    
    @OneToOne // 일대일 관계 매핑
    @JoinColum(name = "locker_id", unique = true)
    private Locker locker;
    
}

@Entity
public class Locker {
	@Id @GeneratedValue
    @Colum(name = "locker_id")
    private Long id;
    
    private String name;
    
    @OneToOne(mappedBy = "locker") // mappedBy로 연관관계의 주인이 아님을 나타냄
    private Member member;
}

(3) 대상 테이블에 외래키가 존재하는 양방향

@Entity
public class Member {
	@Id @GeneratedValue
    @Colum(name = "member_id")
    private Long id;
    
    private String username;
    
    @OneToOne // 일대일 관계 매핑
    @JoinColum(name = "member_id", unique = true)
    private Locker locker;
    
}

@Entity
public class Locker {
	@Id @GeneratedValue
    @Colum(name = "locker_id")
    private Long id;
    
    private String name;
    
    @OneToOne(mappedBy = "locker") // mappedBy로 연관관계의 주인이 아님을 나타냄
    private Member member;
}

4. 다대다(N:M) 관계

관계형 DB는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없으므로 연결 테이블을 추가해서 일대다, 다대일 관계로 풀어내야함


ORDER 테이블을 MemberProduct 엔티티로 만들어 다대다 관계를 일대다, 다대일 관계로 품
이때 ORDER 테이블의 기본키는 (member_id, product_id)로 설정할 수도 있고
order_id로 따로 설정할 수도 있음
-> order_id를 만들어 아무 상관없는 값을 기본키로 만드는 것이 나음






참고: 인프런 자바 ORM 표준 JPA 프로그래밍 기본편 - 김영한

profile
핸수

0개의 댓글