몬그로이

JPA - Entity 연관 관계 본문

Organizing Docs/Java Docs

JPA - Entity 연관 관계

Mon Groy 2024. 5. 27. 20:00

Table끼리의 연관관계와 Entity간의 연관관계 차이로 발생하는

자바의 표현 방식을 익혀보자

 

한 명의 고객이 여러가지 음식을 주문한 상황을 

표에 그리면 나열을 해야하는데 Spring 의 Table 은 그렇게 만들 수가 없음

Entity 하나가 row 하나이고 column 에 해당하는 키값을 각각 하나씩만 가지기 때문

따라서 연관되었다는 의미를 컬렉션을 이용해서 표현함


다대일 단방향 관계

 

Food class 에서 표현하길

@ManyToOne

@JoinColumn(name="user_id") 

 

User class 에서 표현하길

(아무 것도 없음)

**Food가 user를 참조하지만

User는 Food 를 참조하지 않는 상황이기 때문임

즉, User를 통해 음식을 조회하는 경우가 없을 때 사용하는 표현방식임

굳이 조회하겠다면 

앞서 배운 양방향 관계로 설정한 다음 조회해야 함

 

방향이란건 무언가를 참조한다는 의미

테이블에서는 없던 "방향"이라는 개념이 "조회"를 기준으로 생겨난 것이고,

코드로도 표현하는 방식이 발생하게 된 것이다

 

Table 끼리의 관계와 Entity 끼리의 관계에 차이가 있기 때문에

조회할 때 "특정한 방식"이 생겨난 것임

더 상세히 말하자면 Entity끼리의 관계는 객체관계이기 때문에 발생한 방식인 것

 

entity가 참조를 하려면 참조할 객체를 필드에 가지고 있어야 하고

참조하는 객체를 기준으로 참조되는 객체를 표현한 것을 두고 방향이라는 개념이 생겨난 것

 

Table에 새로운 Column을 들이는 Entity가 Owner로

외래키의 주인 이라고 표현한다

외래키의 주인만 참조한 외래키를 등록, 수정, 삭제할 수 있고

외래키의 주인이 아닌 쪽은 외래키를 읽는 것만 가능함

 

 외래키의 주인

@JoinColumn(null여부, unique 여부 등을 지정)

 

OneToOne 단방향일 때

 

참조하는 (Owner) / 참조되지 않는 Table 을 Entity로 표현함

@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITYU)
    private Long id;
    private String name;
    private double price;
    
    @OneToOne
    @JoinColumn(name = "user_id")
    private User user;
 
cs

 

 

참조되는 / 참조하지 않는 Table을 Entity로 표현함

@Entity
@Table(name = "users")
public class User{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITYU)
    private Long id;
    private String name;
 
cs

 

 

OneToOne 양방향일 때

참조하는 (Owner) / 참조되는 Table 을 Entity로 표현함

@JoinColumn 생략 가능 

**주의! 일대다일 경우 생략하면 중간Table이 생성됨 

@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITYU)
    private Long id;
    private String name;
    private double price;
@OneToOne
    @JoinColumn(name = "user_id") //Column 이름 (생략가능)
    private User user; //참조한 클래스 선

 

 

참조하는 / 참조되는 Table 을 Entity로 표현함

- Owner 는 아니어서 fk가 Table에 나타나지 않음

- mappedBy 로 주인이 있음(내가 주인아님)을 표시

** ~에 의해서 "user"라고 지정됨을 의미  

@Entity
@Table(name = "users")
public class User{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITYU)
    private Long id;
    private String name;
 
    @OneToOne(mappedBy = "user") //user를 선언한 Food(Owner)에 의해 매핑됨
    private Food food //그게 여기에 있소~
 
cs
 
 

 

 

mappedBy 는 양방향일때만 사용한다

 

일대다 단방향일 때

Owner: Food (일대다의 일)

@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITYU)
    private Long id;
    private String name;
    private double price;
    
    @OneToMany
    @JoinColumn(name = "food_id"
    private List<User> = users;
cs

 

User (일대다의 다) - 아무런 표시도 하지 않는다

@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITYU)
    private Long id;
    private String name;
 
cs

 

일대다 양방향일 때

Owner: Food (일대다의 일)

@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITYU)
    private Long id;
    private String name;
    private double price;
    
   @OneToMany (mappedBy = "user")
    private List<User> = users;
cs

 

**일대다일때 mappedBy는 지원하지만

다대일일 때 mappedBy를 지원하지 않는다

**특이점: Owner 이지만 @JoinColumn이 없고 mappedBy가 있

 

User (일대다의 다)

@Entity
@Table(name = "User")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITYU)
    private Long id;
    private String name;
    
    @ManyToOne
    @JoinColumn(name = "food_id"
    private Food food;
cs

**특이점: Owner가 아니지만 mappedBy가 없고 @JoinColumn이 있다


결론

  Owner(외래키의 주인) FK객체
Annotation @JoinColumn mappedBy Annotation @JoinColumn mappedBy
일대일 단방향 @OneToOne name="fk_id" x x x x
일대일 양방향 @OneToMany name="fk_id" x @OneToOne x fk
일대다 단방향 @OneToMany name="owner_id" x x x x
일대다 양방향 @OneToMany x fk @ManyToOne name="owner_id",
insertable = false,
updatable = false
미제공
다대일 단방향 @ManyToOne name="fk_id" x x x x
다대일 양방향 @ManyToOne name="fk_id" x @OneToMany x fk
다대다 단방향 @ManyToMany @JoinTable 내 x x x x
@JoinTable(name = "middle", joinColums = @JoinColumn(name = "fk_id)) x
다대다 양방향_가상 중간 Table @ManyToMany @JoinTable 내 x @ManyToMany x fkList
@JoinTable(name = "middle",
joinColums = @JoinColumn(name = "owner_id),
inverseJoinCoumns = "@JoinColumn(name = "fk_id))
x
다대다 양방향
_중간Table
(FK객체로 바뀜) @OneToMany x fk
중간테이블(Owner) Owner_Origin
@ManyToOne name = Owner_Origin_id
name = fk_id
x @OneToMany x Owner_Origin

 

 

!! mappedBy : Owner가 이렇게 선언했다

참조하는 대상이 여럿일 때 컬렉션 객체로 표기한다

**JoinTable 은 PK가 없음 << JPA에서 만들어 주기 때문

 

 

FK에서 Owner테이블에 추가하기 = 메서드를 따로 만든다

 

 

 

'Organizing Docs > Java Docs' 카테고리의 다른 글

자바의 정석 5. 배열(Array)  (0) 2024.06.18
쓰기 지연 저장소와 지연 로딩  (0) 2024.06.04
Regrex 정규표현식(Regular Expression)  (0) 2024.05.31
생성자  (0) 2024.05.23
다형성(Polymorphism)  (0) 2024.05.23