양방향관계 + 단방향 최종

1

JPA

목록 보기
11/15

  • B가 C를 사용 (B가 C를 has-a관계, 단방향)
  • B가 R을 사용 (B가 R를 has-a관계, 단방향)

  • 서로 의존 : 방향 관계
  • 주문상세에 어떤 상품이 있는지를 확인할 수도있고, 상품에서 주문이 몇개 됐는지 확인하고 싶을 수 있다. -> 단방향 + 단방향 = 양방향
    일반적으로 객체는 양방향이다.
    하지만 엔티티객체를 양방향으로 만들기 위해서는 양쪽 클래스에 has-a관계를 맺어줘야 한다.

  • 주문에는 기본 + 상세가 있다보니까 , 주문은 한꺼번에 insert가 돼야함.
    원상복구도 한번에 돼야하기 때문에 life cycle이 같이 돌아가게됨. 주문상세가 따로 insert가 되면 안됨
    또한, 주문상세는 지워지는데 기본은 안지워진다? 안됨. → 주문 상세용 repository를 따로 만들 이유가 없음.
    -> 모든 클래스에 따라서 Repository를 만들 필요는 없다.
  • 게시글과 답글은 따로 insert, delete들을 해줘야하기 때문에 repository를 각각만들지만,
    SQL이 한번에 이뤄지는 경우에는 Repository를 따로 팔 필요가 없다~

  • 주문상세가 자식 entity인데,자식이 있으면 부모를 지울 수 없다.
    ➡︎ 서로 꼬리에 꼬리를 물고있는 상태이기 때문에 양방향은 조심해야 한다.
  • 부모를 삭제하려 하면 자식을 없었던 것 처럼 null값으로 자꾸 update를 하려함.
    • 이 현상을 없애기 위해서 해당 자료에 묶여있으니까 함부로 수정이나 삭제하지 말라고 mappedBy로 엮어서 알려줌.
  • Line.class(주문상세)가 갖고있는 lineP에 묶여있는데 이를 P가 멤버변수인 pLines와 연결돼있는 객체(Line)에 묶여있다(mappedBy) 라고 함
    P에서 참조하고 있는 joinColumn을 지우고, mappedBy 추가
    • 양방향 관계에서만 쓰이는 property, 연관관계에서의 주 필드명을 적어라

      부모를 삭제하려하면 자식 객체 값을 null로 막 넣으려고 하는게 아니라, 자식이 먼저 삭제되고 부모가 삭제되게끔 함


  • 부모가 먼저 채워지고 자식이 fk로 부모를 가짐
    info가 여러 line을 갖고 싶다 -> info가 line만 가지고 있는게 아니라 자식엔티티(line)에서 부모엔티티(info) 클래스를 has-a관계로 가지고있어야 fk로 연결한 효과가 난다.

  • line의 기존 Pk를 객체로 변경

  • Info의 lines는 Line클래스에서 선언한 line_no를 fk로 가진다.
    -> ManyToOne으로 fk 연결을 해줌


  • 게시글과 댓글
    테이블간의 관계는 b_tbl 1: r_tbl N

  • rNo = 댓글. rb_no: fk로 사용될 컬럼
    @OneToMany @JoinColumn을 쓸 때 @JoinColumn에 fk로 쓸 컬럼을 지정하면됨
    -> rb_no : fk coloum, 클래스의 관계에서 봤을 때 List< R> rs 와 rb_no와 연결이 돼있는 것임

  • 테이블이 생성이 될 때 b_no라는 pk와 r_no라는 pk가 만들어지면서 rb_nob_no을 참고하는 것임 -> FK로 쓰는 것
    테이블만들때 컬럼이 생성되고 r용테이블이 만등러질때 b_norb_no가 참조하게 되는 것임 : 단방향

  • mappedBy설정 없이 @JoinColumn을 했을 경우 부모인 게시글을 삭제하려고 하면 부모쪽에서 delete를 수행 -> 자식쪽의 값을 null로 update를 하려할거 → 그냥 이대로 냅둘거면 그냥 @JoinColumn을 쓰면 됨 → 위험한 방법임
    → 게시글처럼 잘못된 데이터가 들어가도 관계없는 테이블이 있고, 안되는(트랜잭션이 중요한) 테이블이 있다.

    • 게시글의 데이터보다 주문에 대한 데이터는 훨씬 중요한 데이터임.
      가장 기본적인 히스토리 이기 때문에 망가지면 안됨 → JoinColumn쓰면 안됨
      → mappedBy 사용 → mappedBy를 사용한다고 fk를 만드는게 아니라 누구한테 엮여있다는 것을 표현할 뿐임.
    • 부모가 자식 누구에게 엮여있다 = 부모를 맘대로 삭제할 수 없다.
      부모를 삭제하면 엮여있는 애들도 삭제할것이라는 뜻. fk와는 관계 없음
      → 이때는 fk를 연결해주기 위해서 자식쪽에서 연결해줘야 한다.
      → 자식쪽에서 @JoinColumn 적고, @ManyToOne으로 연결해줘야함.
  • @OneToMany : 자식쪽에서 부모를 참조하기 위한 용도
    자료가 먼저 저장되는 곳이 부모, 그 pk를 참고해서 나중에 저장되는 곳이 자식

  • 주문기본: 부모, 상세: 자식
    부모에서 강제로 자식과 연결하기 위해서는 @OneToMany & @JoinColumn
    -> 부모에서 자식들을 참고할때만 @OneToMany 씀 & mappedBy 는 부모에!!
    자식에서 부모의 pk를 fk로 등록하기 위해서는 @ManyToOne & @JoinColumn

  • 주문 기본과 상세의 repository는
    기본을 추가하면서~ 상세들도 같이 추가하기 때문에 orderRepository 하나만 만들어도 됨

    • CrudRepository< , > 핵심 엔티티는 OrderInfo로 설정.
      상세는 OrderInfolines에 상세 정보가 담겨있으니 그걸 이용하면 됨

    • 양방향을 쓸건지, 단방향을 쓸건지는 정해져있지 않음. 본인의 서비스에 따라 달라질것!!

      • erd에 맞추는 것도 아님!

양방향에서..

부모

@OneToMany(fetch = FetchType.EAGER,
          cascade = CascadeType.ALL,
          mappedBy = "info")

@OneToMany

  • mappedBy ="자식의 멤버변수 이름"

    자식

    @ManyToOne
      @JoinColumn(name="line_no")  // info에서 fk역할을 할 변수
      private Info info;

    @ManyToOne

    • 부모의 Pk를 Fk로 가져옴
    • @JoinColumn(name="자신 테이블에 설정할 컬럼이름")
    • private 부모객체 멤버변수이름;

단방향에서..

	@ManyToOne //  객체간 단방향 연관관계 설정
	@JoinColumn(name = "b_id", nullable = false)  // 조인 시(FK)에 사용할 컬럼명이다. -> FK에 해당하는 컬럼을 넣어주면됨
	private C bC; // 게시글을 쓴 작성자 정보
//	@OneToMany(fetch = FetchType.EAGER) // EAGER 설정 대신 테스트코드에 @Transactional, @Commit 추가할 수 있다.
	@OneToMany  // b클래스가 r클래스를 has-a관계로 가짐
	@JoinColumn(name = "rb_no") // fk에 참여할 컬럼명
	private List<R> rs;

@ManyToOne

  • @JoinColumn(name="자신의테이블에서 쓸 본인컬럼이름")
    private 가져올객체 멤버변수;

@OneToMany

  • @JoinColumn(name="가져올 객체의 컬럼이름")
    private List<가져올객체> 멤버변수;
profile
백엔드를 공부하고 있습니다.

0개의 댓글