연관관계매핑 - 다대일관계

 

 

 

<다대일 단방향>

 

 

다대일 단방향에 대한 모식도를 나타내면 위와 같다.

 

다쪽에서 외래키를 관리하고 Member쪽에서만 Team를 참조하는 형태이다.

 

가장 많이 사용하는 형태이다.

 

@Entity
@Data
public class Member{

	@Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    
    @Column(name = "USERNAME")
    private String username;
    
    
    //team과의 연관관계 설정
    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;
    
    
}

@Entity
@Data
public class Team{

	@Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    
    private String name;
    
    
}

 

엔티티는 이러한 형태로 나타난다.

 

 

<다대일 양방향>

 

 

다(Member 쪽이 연관관계 주인)

Team에서도 Member를 참조해서 조회할 수 있는 형태 

Member를 조회시 Team도 함께 조회되는 쿼리가 많아진다 ==> 다대일 양방향으로 매핑하자.

 

@Entity
@Data
public class Member{

	@Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    
    @Column(name = "USERNAME")
    private String username;
    
    
    //team과의 연관관계 설정
    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;
    
    
}

@Entity
@Data
public class Team{

	@Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    
    private String name;
    
    
    //양방향 연관관계 설정
    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();
    
    
}

 

엔티티의 형태는 위와 같이 작성된다.

 

 

 

 

<일대다 단방향>

 

 

 

권장하지 않는 모델이다.

 

Team엔티티에서 members에 변경이 일어난다면 MEMBER 테이블에서도 수정이 필요하다.

 

@Entity
@Data
public class Member{

	@Id @GeneratedValue
	@Column(name = "MEMBER_ID")
	private Long id;
    
    	@Column(name = "USERNAME")
    	private String username;
    
}

@Entity
@Data
public class Team{

	@Id @GeneratedValue
    	@Column(name = "MEMBER_ID")
    	private Long id;
    	
    	private String name;
        
    	@OneToMany
    	@JoinColumn(name="TEAM_ID")
    	private List<Member> members = new ArrayList<>();
    
    
}

 

엔티티는 위와 같이 작성된다.

 

만약 

 

Member member = new Member();

member.setUsername("member1");

em.persist(member);

 

Team team = new Team();

team.setName("teamA");

 

team.getMembers().add(member);

em.persist(team);

 

tx.commit();

 

위와 같은 식이 실행되면 실행되는 쿼리중에서 member 테이블에서 update가 실행되는 쿼리가 나온다. 

 

 

* 일대다 단방향은 일대다(1:N) 에서 일(1)이 연관관계의 주인

* 테이블 일대다 관계는 항상 다(N) 쪽에 외래 키가 있음.

* 객체와 테이블의 차이 때문에 반대편 테이블의 외래 키를 관리하는 특이한 구조

* @JoinColumn을 꼭 사용해야 한다. 그렇지 않으면 조인 테이블 방식을 사용한다. (중간에 테이블이 하나 추가된다.)

 

단점 

- 엔티티가 관리하는 외래 키가 다른 테이블이 있다.

- 연관관계 관리를 위해 추가로 update문이 실행된다.

- 일대다 단방향 매핑보다는 다대일 양방향 매핑을 사용을 권장한다.

 

 

일대다 양방향은 공식적으로 지원하는 매핑이 아니다. 다대일 양방향으로 사용을 권장한다. 그러므로 다루지 않는다.

 

 

 

<일대일 관계>

 

* 일대일 관계는 반대도 똑같음

* 주 테이블이나 대상 테이블 중 외래 키 선택 가능

 

 

 

 

회원 하나당 1개의 락커만을 가질 수 있다는 전제의 구조이다.

 

양방향으로 설정하고 싶다면 Locker에 Member 객체를 추가해주면 된다.

 

 

 

<다대다 관계>

관계형 DB는 테이블 2개로 다대다 관계를 나타낼 수가 없다. 그러므로 연결 테이블을 통해서 일대다, 다대일 관계로 해결해야한다.

 

 

 

 

 

 

객체는 2개로 다대다 관계를 표현이 가능하다.

 

하지만 연결테이블의 추가로 쿼리도 복잡하게 나가고 관리도 귀찮아진다. 연결테이블이 단순히 연결만 하고 끝나지 않기도 하다. 

 

중간테이블을 아예 엔티티로 표현하여 관리하면 한결 더 수월해진다.

 

@Entity
@Data
public class Member {
	
    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    
    @Column(name = "USERNAME")
    private String username;
    
    @OneToMany(mappedBy = "member")
    private List<MemberProdcut> memberProducts = new ArrayList<>();
    
}

@Entity
@Data
public class MemberProdcut {
	
    @Id @GeneratedValue
    private Long id;
    
    @ManyToOne
    @JoinColumn(name = "MEMBER_ID")
    private String username;
    
    @ManyToOne
    @JoinColumn(name = "PRODUCT_ID")
    private Product product;
    
}

@Entity
@Data
public class Product {
	
    @Id @GeneratedValue
    private Long id;
    
    private String name;
    
    @OneToMany(mappedBy = "product")
   	private List<MemberProduct> memberproducts = new ArrayList<>();
    
}

'JPA' 카테고리의 다른 글

[JAVA]JPA_즉시로딩과 지연로딩  (0) 2024.10.30
[JAVA] JPA_상속관계 매핑  (0) 2024.10.27
[JAVA] JPA_연관관계 매핑  (0) 2024.10.27
[JAVA] JPA_영속성 관리  (0) 2024.10.18
[JAVA] JPA란?  (0) 2024.10.18

+ Recent posts