[JPA] JPA(Java Persistence API) 연관관계

allnight5·2022년 12월 19일
0

JPA

목록 보기
3/5

jpa양방향 연관관계 참조 1
Jpa란 무엇인가 참조1
JPA는 자바 진영에서 ORM(Object-Relational Mapping) 기술 표준으로 사용되는 인터페이스의 모음이다. 그 말은 즉, 실제적으로 구현된것이 아니라 구현된 클래스와 매핑을 해주기 위해 사용되는 프레임워크이다. JPA를 구현한 대표적인 오픈소스로는 Hibernate가 있다.


ORM(Object-Relational Mapping)

우리가 일반 적으로 알고 있는 애플리케이션 Class와 RDB(Relational DataBase)의 테이블을 매핑(연결)한다는 뜻이며, 기술적으로는 어플리케이션의 객체를 RDB 테이블에 자동으로 영속화 해주는 것이라고 보면된다.


장점

  • SQL문이 아닌 Method를 통해 DB를 조작할 수 있어, 개발자는 객체 모델을 이용하여 비즈니스 로직을 구성하는데만 집중할 수 있음.
    (내부적으로는 쿼리를 생성하여 DB를 조작함. 하지만 개발자가 이를 신경 쓰지 않아도됨)
  • Query와 같이 필요한 선언문, 할당 등의 부수적인 코드가 줄어들어, 각종 객체에 대한 코드를 별도로 작성하여 코드의 가독성을 높임
  • 객체지향적인 코드 작성이 가능하다. 오직 객체지향적 접근만 고려하면 되기때문에 생산성 증가
  • 매핑하는 정보가 Class로 명시 되었기 때문에 ERD를 보는 의존도를 낮출 수 있고 유지보수 및 리팩토링에 유리
  • 예를들어 기존 방식에서 MySQL 데이터베이스를 사용하다가 PostgreSQL로 변환한다고 가정해보면, 새로 쿼리를 짜야하는 경우가 생김. 이런 경우에 ORM을 사용한다면 쿼리를 수정할 필요가 없음

단점

  • 프로젝트의 규모가 크고 복잡하여 설계가 잘못된 경우, 속도 저하 및 일관성을 무너뜨리는 문제점이 생길 수 있음
  • 복잡하고 무거운 Query는 속도를 위해 별도의 튜닝이 필요하기 때문에 결국 SQL문을 써야할 수도 있음
    학습비용이 비쌈

중요!

'부모 post 조회 시 자식 comment 까지 조회가 되므로 연쇄적으로 자식 comment 의 자식 엔티티인 commentLike 쿼리도 같이 나가야 하지 않을까?'

좋은 지적이다. 하지만, post 의 자식 엔티티는 post 엔티티에 일대다(@OneToMany) 필드로 매핑되어 있기 때문 바로 조회가 되어 select 쿼리가 나가지만, post 의 자식 comment 의 자식인 commentLike 는 바로 조회가 되지 않고 아래와 같이 직접적으로 comment 엔티티의 commentLikeList 에 접근 시 쿼리가 나간다.

List<Comment> commentList = findPost.getCommentList();
        for (Comment comment : commentList) {
            System.out.println("test : " + comment.getCommentLikeList());
        }

참조사이트

@ManyToOne
@ManyToOne 매핑의 기본 fetch가 EAGER라서 생략해도 EAGER로 동작한다
(fetch = FatchType.EAGER)와(fetch = FatchType.LAZY)
EAGER(즉시로딩), LAZY(지연로딩)

EAGER는 사전적 의미인 열심인, 열렬한 처럼 Member를 조회하면 연관관계에 있는 Team 역시 함께 조회는 반면에, LAZY는 게을러서 Member만 조회해오고 연관관계에 있는 나머지 데이터는 조회를 미룬다.

사용처는 User와 연관관계에 있는 데이터 테이블 Post을 항상 함께 불러와야할때는 EAGER를 하나의 테이블 User만 사용하거나 드물게 연관테이블을 Post불러올때는 User을 부르고 Post쿼리를 한번더 날려 조회하는것이 좋을때 LAZY를 사용하는것이다.

가급적이면 지연 로딩(Lazy Loading)만 사용
참조사이트
1-3. 연관관계 매핑 ( 1 : N ) 양방향 매핑

이론
.

  • 양방향 매핑
    • 현재 객체는 Member가 Team을 가졌으나, Team은 Member를 가지지 못한다.
    • 객체 참조와 외래키의 가장 큰 차이점
    • 테이블은 FK만 있으면 양쪽의 연관관계를 알 수 있다.
    • Member : Team = : n : 1 => @ManyToOne
    • Team : Member = 1 : n => @OneToMany
      .
  • 테이블 연관관계
    • 관계 1개
    • Member 테이블 입장에서 Team 테이블 조인 가능
    • Team 테이블 입장에서 Member 테이블 조인 가능
      .
  • 객체 연관관계
    • 관계 2개
    • Member 객체에서 Team 객체로 연관관계 1개 ( 단방향 )
    • Team 객체에서 Member 객체로 연관관계 1개 ( 단방향 )
      .
  • 관리의 딜레마
    • 둘 중 하나로 외래키를 관리해야 한다.
    • Member에서 Team으로 가는 Team 참조 값과, Team에서 Member로 가는 member 참조 값이 있다.
    • Member에서 Team값이 수정 되었을 때 Member table의 TEAM_ID가 수정되야 하는지, Team에 있는 members를 수정했을 때 Member table의 TEAM_ID가 수정되야 하는지?
      -> DB 입장에서는 Member table에 있는 TEAM_ID만 update하면 된다 -> 룰 ( 주인 ) 이 생긴다.
      .
  • 연관관계의 주인 ( Owner ) - 양방향 매핑 규칙
    • 객체의 두 관계 중 하나를 연관관계의 주인으로 지정
    • 연관관계의 주인만이 외래 키를 관리 ( 등록, 수정)
    • 주인이 아닌쪽은 읽기만 가능
    • 주인은 mappedBy 속성 사용 x
      -> mappedBy : 내가 누군가에 의해서 mapping 되었다는 뜻
    • 주인이 아니면 mappedBy 속성으로 주인 지정

2. 연관관계 매핑 주의 할 점


양방향 연관관계에서 주의 할 점

  • 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정해 주어야 한다.
  • 연관관계 편의 메서드를 생성해 주어야 한다.
  • 양방향 매핑시에 무한 루프를 조심해야 한다.
    -> toString(), lomlok lib를 조심해야 한다.

3. 양방향 매핑 정리

  • 단방향 매핑만으로도 이미 연관관께 매핑은 완료
    • 양방향 매핑은 반대 방향으로 조회기능이 추가 된 것 뿐.
    • 양방향 사용 이유 : JPQL에서 역 방향으로 탐색할 일이 많음
    • 단방향 매핑을 잘 하고 양방향은 필요 할 때 추가해도 됨 (테이블에 영향을 주지 않음 )
  • 결론: 객체 입장에서 양방향 매핑이 필수는 아님.
    • 연관관계의 주인을 정하는 기준
    • 비즈니스 로직을 기준으로 연관관계의 주인을 선택하면 안됨
    • 연관관계의 주인은 외래 키의 위치를 기준으로 정해야함
profile
공부기록하기

0개의 댓글