연관 관계 매핑(Association Mapping)

JOY🌱·2023년 4월 10일
0

🐸 JPA

목록 보기
4/8
post-thumbnail

💁‍♀️ 연관 관계란,
서로 다른 두 객체가 연관성을 가지고 관계를 맺는 것


🙋‍ 연관 관계의 분류

  • 방향(Direction)에 따른 분류
    참조에 의한 객체의 연관 관계는 단방향임. 테이블의 연관 관계는 외래 키를 이용하여 양방향 연관 관계의 특징을 가짐
    객체간의 연관 관계를 양방향으로 만들고 싶을 경우 반대 쪽에서도 필드를 추가해서 참조를 보관하면 됨.
    하지만 엄밀하게 이는 양방향 관계가 아니라 단방향 관계 2개로 볼 수 있음.
    1-1. 단방향 연관 관계
    1-2. 양방향 연관 관계
  • 다중성(Multipleicity)에 대한 분류
    연관 관계가 있는 객체 관계 혹은 테이블 관계에서 실제로 연관을 가지는(매핑되는) 객체의 수 또는 행의 수에 따라 분류됨
    2-1. 1:1(OneToOne) 연관 관계
    2-2. 1:N(OneToMany) 연관 관계
    2-3. N:1(ManyToOne) 연관 관계
    2-4. N:N(ManyToMany) 연관 관계

🙋‍ 연관 관계를 가지는 엔티티를 조회(SELECT)하는 방법

  • 객체 그래프 검색(객체 연관관계를 사용한 조회)
  • 객체 지향 쿼리 사용(JPQL)

👀 ManyToOne (N:1)

GitHub

👉 @JoinColumn

💁‍♀️ 외래키를 매핑할 때 사용하는 어노테이션

@JoinColumn(name="CATEGORY_CODE")
@ManyToOne(cascade=CascadeType.PERSIST)	// 영속성 전이 설정
private Category category;

@JoinColumn의 속성

  • name : 매핑할 외래키의 이름
  • referencesColumnName : 외래키가 참조하는 대상 테이블의 컬럼명
  • foreignKey : 외래키 제약 조건을 직접 지정할 수 있으며 테이블 생성 시에만 적용됨
  • unique, nullable, insertable, updatable, columnDefinition, table : @Column의 속성과 동일

👉 @ManyToOne

💁‍♀️ N:1 관계에서 사용하는 어노테이션

@JoinColumn(name="CATEGORY_CODE")
@ManyToOne(cascade=CascadeType.PERSIST)	// 영속성 전이 설정
private Category category;

@ManyToOne의 속성

  • optional : false로 설정하면 연관된 엔티티가 항상 있어야함
  • cascade : 영속성 전이 기능을 사용 (연관된 엔티티를 함께 영속성으로 관리한다는 의미)
  • orphanRemoval : true로 설정하면 고아 객체 제거

💁‍♀️ 영속성 전이란,
특정 엔티티를 영속화할 때 연관된 엔티티도 함께 영속화 한다는 의미

  • ex) cascade=CascadeType.PERSIST를 설정하면 Menu를 저장하기 전에 Category부터 저장하게 됨

👀 OneToMany (1:N)

GitHub

👉 @OneToMany

💁‍♀️ 1:N 관계에서 사용하는 어노테이션

@JoinColumn(name="CATEGORY_CODE")
@OneToMany(cascade=CascadeType.PERSIST) // 카테고리를 추가 하는 동시에 메뉴도 추가하고 싶다면 영속성 전이 속성을 반드시 추가해야함
private List<Menu> menuList;

👀 BiDirection

GitHub

🙋‍ 양방향 연관관계 매핑
데이터베이스의 테이블은 외래키 하나로 양방향 조회가 가능하지만 객체는 서로 다른 두 단방향 참조를 합쳐서 양방향이라고 함
따라서 두 개의 연관 관계 중 연관 관계의 주인을 정하고, 주인이 아닌 연관 관계를 하나 더 추가하는 방식으로 작성
반대 방향으로 access 하여 객체 그래프 탐색을 할 일이 많은 경우 양방형 연관관계 매핑을 사용 (항상 사용하는 것이 아님)


🙋‍ 연관 관계의 주인을 정하는 기준
양방향 연관 관계 시 연관 관계의 주인(Owner)라는 이름으로 인해 오해가 있을 수 있음
비즈니스 로직 상 더 중요하다고 연관 관계의 주인으로 선택하면 안되며,
비즈니스 중요도를 배제하고 단순히 외래키 관리자의 의미를 부여해야함
연관 관계의 주인'외래 키(FK)를 가지고 있는 엔티티'

◼ Menu Entity

/* 연관 관계의 주인은 Menu (FK를 가지고 있기 때문) */
@Entity(name="bidirection_menu")
@Table(name="TBL_MENU")
public class Menu {

	@Id					
	@Column(name="MENU_CODE")
	private int menuCode;
	@Column(name="MENU_NAME")
	private String menuName;
	@Column(name="MENU_PRICE")
	private int menuPrice;
	
	/* 연관 관계의 주인의 경우 전과 같은 방식으로 연관 관계 매핑을 처리하면 됨 */
	@JoinColumn(name="CATEGORY_CODE")
	@ManyToOne
	private Category category;
	
	@Column(name="ORDERABLE_STATUS")
	private String orderableStatus;
    
    /* 생성자, getter&setter, toString */

}

◼ Category Entity

mappedBy

@Entity(name="bidirection_category")
@Table(name="TBL_CATEGORY")
public class Category {

	@Id
	@Column(name="CATEGORY_CODE")
	private int categoryCode;
	@Column(name="CATEGORY_NAME")
	private String categoryName;
	@Column(name="REF_CATEGORY_CODE")
	private Integer refCategoryCode;
	
	/* mappedBy : 연관 관계의 주인을 정하기 위해 연관 관계의 주인이 아닌 객체에 mapperBy를 사용하여 연관 관계 주인 객체의
	 * 필드명을 매핑 시켜놓으면 로직으로 양방향 관계를 적용시킬 수 있음 */
	@OneToMany(mappedBy="category")
	private List<Menu> menuList;
    
    /* 생성자, getter&setter, toString */
    /* !! stackOverFlowError를 방지하기 위해 toString에서 menuList 제거 !! */

}
profile
Tiny little habits make me

0개의 댓글