[SPRING:이론] 9 : Entity 연관 관계 - 2

김승수·2024년 5월 29일
0

SPRING

목록 보기
8/27

⏰ 2024. 05. 29 수

✔ 스프링 이론 강의를 듣고 정리하면서 작성했습니다.

💡 목차

  1. N:1 관계
  2. 1:N 관계
  3. N:M 관계

N:1 관계

N:1 관계 (@ManyToOne)

  • @ManyToOne 애너테이션은 N:1 관계를 맺어주는 역할을 한다.

N:1 단방향관계

@Entity
@Table(name = "entity1")
public class Entity1 {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToOne
    @JoinColumn(name = "entity2_id")
    private Entity2 entity2;
}


@Entity
@Table(name = "entity2")
public class Entity2 {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	private String name;
}
  • Entity1이 N 관계로 외래키의 주인

N:1 양방향관계

@Entity
@Table(name = "entity1")
public class Entity1 {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToOne
    @JoinColumn(name = "entity2_id")
    private Entity2 entity2;
}


@Entity
@Table(name = "entity2")
public class Entity2 {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	private String name;
    
	@OneToMany(mappedBy = "entity2")
	private List<entity1> entity1List = new ArrayList<>();
}
  • 양방향 참조를 위해 Entity1에서 Java 컬렌션을 사용하여 음식 Entity 참조
  • Entity1이 N의 관계로 외래키의 주인

1:N 관계

1:N 관계 (@OneToMany)

  • @OneToMany 애너테이션은 1:N 관계를 맺어주는 역할을 한다.

1:N 단방향 관계

@Entity
@Table(name = "entity1")
public class Entity1 {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany
    @JoinColumn(name = "entity1_id") 	// entity2 테이블에 entity1_id 컬럼
    private List<Entity2> entity2List = new ArrayList<>();
}


@Entity
@Table(name = "entity2")
public class Entity2 {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	private String name;
}
  • 외래키를 관리하는 주인은 Entity1 이지만 실제 외래키는 Entity2가 가지고 있다.
  • 1:N 관계에서 N 관계의 테이블이 외래키를 가질 수 있기 때문에, 외래키는 N 관계인 entity2 테이블에 외래키 컬럼을 만들어 추가하지만 외래키의 주인인 Entity1을 통해 관리한다.

1:N 양방향 관계

  • 1:N 관계에서는 일반적으로 양방향 관계가 존재하지 않는다.
  • 1:N 관계에서 양방향 관계를 맺으려면 Entity1을 외래키의 주인으로 정해주기 위해 Entity2에서 mappedBy 옵션을 사용해야 하지만 @ManyToOne 애너테이션은 mappedBy 옵션을 제공하지 않는다.
  • N 관계의 Entity인 Entity1에서 @JoinColuminsertableupdatable 옵션을 false로 설정하여 양쪽으로 JOIN 설정을 하면 양방향처럼 설정할 수는 있다. ❗ 권장하지 않음
@JoinColumn(name = "entity1_id", insertable = false, updatable = false)

N:M 관계

N:M 관계 (@ManyToMany)

  • @ManyToMany 애너테이션은 N:M 관계를 맺어주는 역할을 한다.

N:M 단방향 관계

@Entity
@Table(name = "entity1")
public class Entity1 {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToMany
    @JoinTable(name = "midEntity", // 중간 테이블 생성
    joinColumns = @JoinColumn(name = "entity1_id"), // 현재 위치인 Entity1 에서 중간 테이블로 조인할 컬럼 설정
    inverseJoinColumns = @JoinColumn(name = "entity2_id")) // 반대 위치인 Entity2 에서 중간 테이블로 조인할 컬럼 설정
    private List<Entity2> entity1List = new ArrayList<>();
}


@Entity
@Table(name = "entity2")
public class Entity2 {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	private String name;
}
  • Entity1이 외래키의 주인
  • 생성되는 중간 테이블을 컨트롤하기 어렵기 때문에 추후에 중간 테이블의 변경이 발생할 경우 문제가 발생할 가능성이 있다.

N:M 양방향 관계

@Entity
@Table(name = "entity1")
public class Entity1 {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToMany
    @JoinTable(name = "midEntity", // 중간 테이블 생성
    joinColumns = @JoinColumn(name = "entity1_id"), // 현재 위치인 Entity1 에서 중간 테이블로 조인할 컬럼 설정
    inverseJoinColumns = @JoinColumn(name = "entity2_id")) // 반대 위치인 Entity2 에서 중간 테이블로 조인할 컬럼 설정
    private List<Entity2> entity2List = new ArrayList<>();
}


@Entity
@Table(name = "entity2")
public class Entity2 {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	private String name;

	@ManyToMany(mappedBy = "entity2List")
	private List<Entity1> entity1List = new ArrayList<>();
}
  • Entity1이 외래키의 주인
  • 반대 방향인 Entity2에 @ManyToMany 로 Entity1을 연결하고, mappedBy 옵션을 설정하여 외래키의 주인을 설정하면 양방향 관계 맺음이 가능하다.

N:M 관계에서 중간 테이블 직접 생성

  • 중간 테이블 midEntity 직접 생성하여 관리하면 변경 발생 시 컨트롤하기 쉽기 때문에 확장성에 좋다.
@Entity
@Table(name = "entity1")
public class Entity1 {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany(mappedBy = "entity1")
    private List<MidEntity> midEntityList = new ArrayList<>();
}


@Entity
@Table(name = "entity2")
public class Entity2 {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	private String name;

	@OneToMany(mappedBy = "entity2")
	private List<MidEntity> midEntityList = new ArrayList<>();
}


@Entity
@Table(name = "midEntity")
public class MidEntity {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	@ManyToOne
	@JoinColumn(name = "entity1_id")
	private Entity1 entity1;

	@ManyToOne
	@JoinColumn(name = "entity2_id")
	private Entity2 entity2;
}
profile
개발하는 미어캣

0개의 댓글