[Spring] Entity 연관 관계

Jiwoo·2024년 5월 28일
0

Spring

목록 보기
9/19
post-custom-banner

📌 1대 1 관계

@OneToOne

단방향 관계

  • 1 대 1 관계에서는 외래 키의 주인 직접 지정
  • JoinColumn() : 외래 키의 주인이 활용하는 애너테이션 → 컬럼명, null 여부, unique 여부 등 지정
// 음식
@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    @OneToOne
    @JoinColumn(name = "user_id")
    private User user;
}
// 고객
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}

양방향 관계

  • 외래 키의 주인 지정해 줄 때 mappedBy 옵션 사용
  • mappedBy의 속성값은 외래 키의 주인인 상대 Entity의 필드명 의미
  • 외래 키의 주인은 상대 Entity 타입의 필드 가지면서 @JoinColumn() 활용해 외래 키 속성 설정
  • 상대 Entity는 외래 키의 주인 Entity 타입 필드 가지면서 mappedBy 옵션 사용해 속성 값으로 외래 키의 주인 Entity에 선언된 @JoinColumn() 으로 설정되고 있는 필드명 넣어준다
// 음식
@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    @OneToOne
    @JoinColumn(name = "user_id")
    private User user;
}
// 고객
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToOne(mappedBy = "user")
    private Food food;
}

📌 N대 1 관계

@ManyToOne

단방향 관계

// 음식
@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
}
// 고객
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}

양방향 관계

  • 양방향 참조 위해 고객 Entity에서 Java 컬렉션 사용해 음식 Entity 참조
// 음식
@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
}
// 고객
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany(mappedBy = "user")
    private List<Food> foodList = new ArrayList<>();
}

📌 1대 N 관계

@OneToMany

단방향 관계

  • 외래 키를 관리하는 주인은 음식 Entity 이지만 실제 키는 고객 Entity가 가지고 있다
  • 외래 키는 users 테이블에 추가하지만 외래 키의 주인인 음식 Entity 통해 관리
// 음식
@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    @OneToMany
    @JoinColumn(name = "food_id") // users 테이블에 food_id 컬럼
    private List<User> userList = new ArrayList<>();
}
// 고객
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}

양방향 관계

  • 1대 N 관계에서는 일반적으로 양방향 관계 존재 X
  • @ManyToOne 은 mappedBy 속성 제공 X
  • N 관계인 Entity인 고객 Entity에서 @JoinColum의 insertable, updatable 옵션을 false로 설정해 양쪽으로 JOIN 설정하면 가능하긴 하다
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

		@ManyToOne
		@JoinColumn(name = "food_id", insertable = false, updatable = false)
		private Food food;
}

📌 N대 M 관계

@ManyToMany

단방향 관계

  • N: M 관계를 풀어내기 위해 중간 테이블(orders) 생성
  • 생성되는 중간 테이블 컨트롤이 어려워 추후 중간 테이블 변경이 발생할 경우 문제 발생 가능성 有
// 음식
@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    @ManyToMany
    @JoinTable(name = "orders", // 중간 테이블 생성
    joinColumns = @JoinColumn(name = "food_id"), // 현재 위치인 Food Entity 에서 중간 테이블로 조인할 컬럼 설정
    inverseJoinColumns = @JoinColumn(name = "user_id")) // 반대 위치인 User Entity 에서 중간 테이블로 조인할 컬럼 설정
    private List<User> userList = new ArrayList<>();
}
// 고객
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}

양방향 관계

  • 반대 방향인 고객 Entity에 @ManyToMany로 음식 Entity 연결하고 mappedBy 옵션 설정해 외래 키 주인 설정

// 음식
@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    @ManyToMany
    @JoinTable(name = "orders", // 중간 테이블 생성
    joinColumns = @JoinColumn(name = "food_id"), // 현재 위치인 Food Entity 에서 중간 테이블로 조인할 컬럼 설정
    inverseJoinColumns = @JoinColumn(name = "user_id")) // 반대 위치인 User Entity 에서 중간 테이블로 조인할 컬럼 설정
    private List<User> userList = new ArrayList<>();
}
// 고객
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToMany(mappedBy = "userList")
    private List<Food> foodList = new ArrayList<>();
}
post-custom-banner

0개의 댓글