본문 바로가기

JPA

JPA 도입을 위한 이해

JPA 개념

  • Object-Relational Mapping (객체 관계 매핑) 
    • 객체는 객체대로 설계하고, 관계형 데이터베이스는 관계형 데이터베이스대로 설계
    • ORM 프레임워크가 중간에서 매핑

  • JPA 
    • 자바 진영의 ORM 기술 표준으로 인터페이스의 모음
    • 즉, 실제로 동작하것이 아니다.
    • JPA 인터페이스를 구현한 대표적인 오픈소스가 Hibernate

JPA 기본 이해

최근에는 Spring Boot 나 Spring Data JPA 처럼 추상화된 기술 기반의 JPA를 사용하기 때문에

실제 JPA가 어떻게 동작하는지 내부 구조나 원리를 이해하기 쉽지않다.

JPA 자체를 기본부터 이해하면 문제가 발생했을 때 근본적인 원인을 쉽게 찾을 수 있다.

 

연관관계 매핑

  • 객체지향 프로그래밍과 관계형 데이터베이스의 차이점의 문제로 개발자가 중간에서 한땀한땀 SQL을 작성 및 변환 해야한다.
  • JPA와 같은 ORM 프레임워크는 객체와 관계형 데이터베이스를 매핑해주고 SQL을 대신 작성해준다.
  • 이런 이점을 얻으려면 객체와 테이블을 정확하게 매핑하는 것이 중요

영속성 컨텍스트

  • 연관관계 매핑이 객체와 테이블의 매핑 정보를 구성하는 정적인 부분이라면, 영속성 컨텍스트는 JPA 내부 동작 방식을 이해하기 위해 필요한 동적인 부분
  • JPA를 사용하면 객체를 자바 컬렉션에 관리하는 것 처럼 편리하게 데이터베이스에 관리할 수 있다.
  • JPA를 사용하면 객체를 조회하고 객체의 데이터를 변경만 해도 변경 내용이 데이터베이스에 자동으로 반영된다.

Spring Data JPA

  • spring-data 프로젝트는 다양한 데이터 관리 솔루션을 동일한 방식의 인터페이스로 사용할 수 있게 해준다.
  • spring-data-jpa는 spring-data의 인터페이스로 JPA를 다룰 수 있게 해주는 프로젝트이다.

쿼리 메소드 기능

1. 메서드 이름으로 쿼리생성

2. 메서드 이름으로 NamedQuery 호출

3. @Query 어노테이션

장점

  • 코딩량이 줄어듭니다.
  • 도메인 클래스를 중요하게 다룹니다.
  • 비지니스 로직 이해가 쉬워집니다.
  • 더 많은 테스트 케이스 작성 가능합니다.
  • 유지보수하기 좋습니다. (기존 필드 변경 시 모든 SQL 수정 => 필드만 추가하면 됨)
  • 데이터베이스를 유연하게 변경이 가능합니다. (Junit 통합 테스트시에 H2 DB 메모리 모드)

주의

  • JPA 모르면 절대 쓰지마세요.
  • 본인 먼저 JPA 마스터가 되세요.
  • 데이터베이스 설계 마스터가 되세요.
  • 대부분의 문제는 JPA를 모르고 사용해서 발생!

경험했던 문제점

  • 우와! JPA는 엔티티와 데이터베이스를 매칭해주고 쿼리도 자동으로 생성해주고! 정말 짱짱짱이다!
    엇?! 테이블도 자동으로 생성하고 업데이트 해준다고?! 써볼까?!
  • application.yml 설정만하면 끝!
    spring:jpa:hibernate:ddl-auto:create
  • 실행....
  • 어라... Drop table User; Create table User ~~~ 의 로그가 지나간다...... (오싹..)
  • 기존의 테이블은 drop 되고 엔티티와 연결된 새로운 테이블로 생성이 되어버렸다...
  • DDL AUTO 옵션
    • none : 아무것도 실행하지 않음
    • create-drop : SessionFactory 시작시점에 drop 후 create를 실행하며, SessionFactory 종료시 drop을 실행함
    • update : 변경된 스키마를 적용
    • create : SessionFactory 시작시점에 drop을 실행하고 create를 실행
    • validate : 변경된 스키마가 존재하면 변경사항을 출력하고 app을 종료
  •  해당 기능에 대해 자세히 알아보고 썼더라면 문제가 발생하지 않았을 것이다.
  • JPA는 그만큼 학습곡선이 매우 높다. 모르는 상태로 사용하지 말자!

도입하기 위해선?

  • 본인이 작성한 JPQL이 어떤 쿼리로 생성될지 이해
    • 연관관계로 인해 불필요한 join이 발생할 수 있다는 걸 인지해야함
    • SQL을 보고싶다면 로그를 확인해야하는 단점이 있음
  • 지연로딩(LAZY), 즉시로딩(EAGER) 전략 이해
    • 즉시로딩 : 어떤 엔티티를 조회 했을 때, 그 엔티티와 연관된 엔티티가 join이 일어나서 같이 조회되는 것 (@ManyToOne, @OneToOne)
    • 지연로딩 : 엔티티가 실제로 사용되는 시점까지 기다리다가 그제서야 엔티티 조회되는 것 (@OneToMany, @ManyToMany)
    • ex) "댓글 더보기"에서 즉시 로딩을 사용할 경우 "댓글 더보기"를 누르지 않았음에도 이미 댓글이 조회 되어버리기 때문에 성능이 느려질 수 있다.
      이 때는 "댓글 더보기"를 클릭 했을 때 댓글 목록을 불러오도록 하는 지연 로딩 방식이 좋을 것이다.
 

[개념] JPA 프로그래밍 - 03. 영속성 관리

영속성 컨텍스트란? JPA를 이해하는 데 가장 중요한 용어 엔티티를 영구 저장하는 환경 여러 엔티티 매니저가 같은 영속성 컨텍스트에 접근할 수도 있음 엔티티 생명주기 비영속 순수한 객체 상태 영속성 컨텍스..

tjsdud4634.tistory.com

  • 자동 변경 감지
    • 변경 감지(Dirty Checking) : 엔티티의 변경사항을 데이터베이스에 자동으로 반영하는 기능
    • 플러시 -> 엔티티와 스냅샷 비교해서 변경된 엔티티 찾음 -> 수정쿼리 생성 후 쓰기 지연 SQL 저장소에 보냄 -> 데이터베이스에 보내서 커밋
    • 변경 감지는 영속성 컨텍스트가 관리하는 영속 상태의 엔티티에만 적용

  • 언제 영속성 컨텍스트가 플러시 되는가
    • 플러시는 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영
    • 호출 방법
      • em.flush()를 직접 호출
      • 트랜잭션 커밋 시 플러시가 자동 호출
      • JPQL 쿼리 실행 시 플러시가 자동 호출
    • 플러시 모드를 별도로 설정하지 않으면 AUTO(커밋이나 쿼리 실행 시 플러시), COMMIT 모드(커밋할 때만 플러시)는 성능 최적화를 위해 사용할 수 있음
 

[개념] JPA 프로그래밍 - 05. 연관관계 매핑 기초

단방향 연관관계 @ManyToOne 다대일(N : 1) 관계라는 매핑 정보 연관관계를 매핑할 때, 이렇게 다중성을 나타내는 어노테이션 필수 @JoinColumn(name="TEAM_ID") 조인컬럼은 외래키를 매핑할 때 사용 name 속성에..

tjsdud4634.tistory.com

  • JPQL 한계 인식
    • 형식안정성(Type safe)을 보장받을 수 없음
      • JPQL은 쿼리 문자열을 string 으로 작성, criteria도 필드이름을 string으로 넘기는 방식이라 type safe한 방식이 아니다.
      • queryDsl을 사용한다면 쿼리에 오류가 있을 때 컴파일 에러가 발생한다. 이런 걸 type safe 하다고 한다.
    • 동적인 쿼리를 작성할 수 없음
  • 가장 중요한건 같이 달려갈 수 있는 팀!

참고

 

  • [도서] 자바 ORM 표준 JPA 프로그래밍