BackEnd/패캠

[JPA] 연관관계

제이드Jade 2022. 2. 1. 15:28
  • - 클래스 멤버변수로 다른 클래스를 가지고 싶을 때 JPA에서는 id대신 그 객체 자체를 멤버로 가지고 그걸 @OneToOne .. 으로 설정하면 자동으로 연관관계가 만들어진다.
  • - ERD에 없어도 양방향으로 @~to~를 달아준다. =>실제 db에서는 소유한 클래스의 id가 필드로 추가된다.

      ㄴ optional = : 해당 클래스는 null값을 가질 수 없다.

      ㄴ mappedBy=”” 주인이 아닌 클래스에서 역으로 주인을 참조할 때. 속성값으로 자기 자신을 적어준다(?), 이걸 하면 주인 클래스는 컬럼에 추가되지 않는다.(주인 클래스를 소유하지 않았으므로)

      ㄴ 1. FK 있는 곳을 주인으로 한다.

          2. 객체의 개념에 따라서 Book에도 BookReviewInfo를 추가하고, BookReviewInfo에도 Book을 추가하는 식으로 양쪽 다 삽입하는 것도 실수를 줄이기 위한 방법이다.

          3. 설계는 단방향(bookReviewInfo->Book)으로 하되, 반대로 접근이 필요해진 곳(Book->BookReviewInfo)에 양방향을 추가하는 식으로 코드를 작성한다.

      ㄴ 양방향으로 서로를 멤버로 가지면 toString의 순환참조가 발생하기 때문에 오류발생

           => @toString.Exclude를 해줘야 한다.

 

  • Many쪽에 FK를 가지고 주인이 되는듯..? => 이쪽에서 one을 조작 / oneToOne은 상황보고 주인을 지정하면 될 듯..?

 

OneToMany

@OneToMany(fetch = FetchType.EAGER)
@ToString.Exclude
@JoinColumn(name="user_id",insertable = false,updatable = false)   

         //user를 통해서 생성,update되면 안된다.(listener 통해서만 가능)
private List<UserHistory> userHistories=new ArrayList<>();
  •  postperist하기 전에는 null이기 때문에 로직에 따라 null포인트 오류가 일어날 수 있으므로 기본생성자로 생성
  • @JoinColum : @OneToMany일때 필요. History가서 user_id컬럼을 만들어서(이미 있으면 그걸로 함) 지금 여기 id를 join시켜 두 테이블 매핑. (안하면 user-userHistory테이블이 또 만들어짐)
  • name을 지정해주지 않으면 user_histories_id의 형태로 history 테이블에 저장됨
  • history에서 속성명이 같은 이름의 카멜케이스로 되어있다면 이 컬럼명은 스네이크 케이스고, 그 스네이크 케이스이름을 joinColumn으로 지정하면 충돌이 생김   

      => history의 컬럼명을 스네이크케이스로 지정한다. :@Column(name="")

  • UserHistory에서 User를 @ManyToOne으로 지정하면 user_id가 만들어지므로 history에서 지정안해줘도 됨

 

@ManyToMany

: 잘 안씀, manyone으로 묶어 manyToOne으로 처리하는 경우가 더 많음. .꼭 필요할 때만 쓰도록

public void addAuthors(Author... authors){
    Collections.addAll(this.authors,authors)
}

 

  • … : 배열 표시 => 컴마로 구분해서 매개변수로 넣어주면 배열로 처리됨
  • Collections.addAll(c, elements) => 콜렉션타입 c에 elements를 모두 add

 

  •  oneto: many쪽에서만 one을 등록해주면 one쪽에서는 자동으로 연결됐었는데 여기선 서로 등록해줘야 함.

       : many쪽에 one의 아이디 필드가 있으므로써 중간테이블을 생략할 수 있었는데, manyTOMany는 어느쪽에 아이디필드가(fk)있어야 하는지 모호하기 때문에 그냥 중간테이블 생성. 생략불가능하다.

 

  •  두 테이블 사이 중간테이블을 만들어서 ManyToOne/OneToMany로 바꿀 수 있다. 관계테이블에 두 객체 관계를 넣고, 두 테이블에도 관계를 넣어준다.