[자바 ORM 표준 JPA 프로그래밍 - 기본편] 1. JPA 소개

jada·2024년 3월 4일
0

Spring 스터디

목록 보기
20/35

SQL 중심적인 개발의 문제점

애플리케이션을 개발할 때에는 객체 지향 언어로 (Java, Scala, Kotlin 등) 개발한다.
그런데 데이터베이스로는 보통 관계형 DB를 많이 사용한다.

즉 우리가 사는 이 시대는 만들어진 객체를 관계형 DB에 보관하고 관리하는 시대이다.
그런데 객체를 관계형 DB에 저장하기 위해서는 INSERT INTO ... 이런 쿼리들을 계속 작성해야 한다. 객체를 관리하기 위해서 관계형 DB와 통신하려면 수많은 SQL을 작성해야 한다는 것이다.

💦 CRUD를 위해 동일한 SQL 문을 계속 반복해서 작성해야 하는 문제점이 있는 것이다!
-> SQL 의존적인 개발을 피하기 어렵다.


🔷 객체와 관계형 데이터베이스의 차이


  1. 상속
  2. 연관관계
  3. 데이터 타입
  4. 데이터 식별 방법

1. 상속
관계형 데이터베이스는 기본적으로 우리가 객체에서 생각하는 상속관계는 없다.


따라서 관계형 DB에서는 다음과 같은 방식으로 상속을 풀어낸다.
데이터베이스 테이블 설계 기법 중 하나인데, 슈퍼 타입, 서브 타입 관계라고 한다.
(데이터를 분리하고 필요할 때 JOIN 해서 가져오는 방식)

  • --> ⏸ 여기서 문제는 ?

  • ALBUM 객체를 저장할 때, 객체를 분해하고 ITEM과 ALBUM 데이터를 모두 저장해야 한다. (INSERT INTO ITEM ...
    ,INSERT INTO ALBUM …)

  • ALBUM 객체를 조회할 때,

      1. 각각의 테이블에 따른 조인 SQL 작성...
      1. 각각의 객체 생성...
      1. 상상만 해도 복잡
      1. 더 이상의 설명은 생략한다.
      1. 그래서 DB에 저장할 객체에는 상속 관계 안쓴다.
  • 반면에 ALBUM 객체를 자바 컬렉션에 저장 / 조회하면?

// 저장
list.add(album);

// 조회
Album album = list.get(albumId);

// 부모 타입으로 조회 후 다형성 활용
Item item = list.get(albumId);

한 줄이면 된다.

2. 연관관계

  • 객체는 참조를 사용한다. 그런데 테이블은 외래키를 사용해서 JOIN을 해야 한다.

  • 따라서 보통 객체를 테이블에 맞추어 모델링한다.

  • 그래야 테이블에 맞춘 객체 저장이 가능하기 때문 !

  • 하지만 이것은 객체다운 모델링이 아니다. 객체는 참조로 연관관계를 맺기 때문 !!!

  • 이렇게 객체다운 모델링을 하게 되면, 데이터베이스에 INSERT 하기 까다로워진다.

  • 객체 모델링 조회는 저장보다 더 까다롭다.

  • 객체를 컬렉션에 저장할 때는 이러한 복잡한 과정이 필요없다..

+)

  • 객체 그래프 탐색

    • 객체는 자유롭게 객체 그래프를 탐색할 수 있어야 한다.

    • 반면에 관계형 DB에 객체를 보관하면, 처음 실행하는 SQL에 따라 탐색 범위가 결정된다.

  • 엔티티 신뢰 문제

    • member.find(~) 에서 뭐가 나오는지, 다른 계층(repository) 등을 까봐야 한다.
    • 신뢰할 수 없으므로 미리 확인하고 연관된 객체들을 로딩해야 하지만,
    • 모든 객체를 미리 로딩할 수는 없다.

    ▶ 계층형 아키텍처 - 진정한 의미의 계층 분할이 어렵다.

    • 물리적으로는 분할 되어 있으나, 논리적으로는 엮여있는 것이다..
  • 비교하기

member1과 member2 는 데이터는 같지만 실제로는 다른 인스턴스이게 된다.

반면, 자바 컬렉션에서 조회하면 똑같은 것으로 조회된다. (같은 참조가 됨)

💫 결론: 객체 지향적으로 설계하기 위해 참조, 상속 등 쓰면서 즉 객체답게 모델링을 할수록 맵핑 작업이 굉장히 많이 늘어난다.

  • 🤔 객체를 Java Collection 에 저장하듯이 DB에 저장할 수는 없을까??
    있다! 그것이 바로 Java Persistenct API (JPA) 라는 기술이다.


JPA 소개

JPA란?

  • Java Persistenct API

  • 자바 진영의 ORM 표준 기술

    • ORM?
      - Object-relational-mapping(객체 관계 매핑)
      - 객체는 객체대로 설계
      - 관계형 데이터베이스는 관계형 데이터베이스대로 설계
      - ORM 프레임워크가 중간에서 매핑 (패러다임의 불일치 등 해결해줌)
      - 대중적인 언어에는 대부분 ORM 기술이 존재한다.

      JPA는 애플리케이션과 JDBC 사이에서 동작한다.


JPA 표준 인터페이스에 하이버네이트를 쓴다.

💖 JPA를 왜 사용해야 하는가?

  • SQL 중심적인 개발에서 객체 중심적인 개발이 가능해진다.

  • 생산성, 유지보수

    • JPA 와 CRUD :
      • 저장: jpa.persist(member)
      • 조회: Member member = jpa.find(memberId)
      • 수정: member.setName(“변경할 이름”)
      • 삭제: jpa.remove(member)
    • 유지보수 : 필드만 추가하면, SQL은 JPA가 처리한다.
  • 패러다임의 불일치 해결
    1.JPA와 상속

    2.JPA와 연관관계
    3.JPA와 객체 그래프 탐색


    • SQL을 직접 다룰 때는 엔티티 계층을 신뢰하기 어려웠다. 하지만 jpa를 사용하면 엔티티(=jpa가 관리하는 자바 객체) 계층을 신뢰할 수 있다.

4.JPA와 비교하기

  • 동일한 트랜잭션 안에서 조회한 엔티티는 같음을 JPA가 보장해준다!

  • 성능, 표준
    JPA의 성능 최적화 기능

    1. 1차 캐시와 동일성(identity) 보장

      • JPA는 같은 데이터베이스 트랜잭션 안에서는 항상 같은 엔티티를 반환해준다.
      • DB Isolation Level이 Read Commit이어도 애플리케이션에서 Repeatable Read 보장

    2. 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)

      • 트랜잭션을 커밋할 때까지 INSERT SQL을 버퍼에 모은다.
      • JDBC BATCH SQL 기능을 사용해서 한번에 SQL을 전송한다.

    • UPDATE, DELETE로 인한 로우(ROW)락 시간 최소화
    • 트랜잭션 커밋 시 UPDATE, DELETE SQL 실행하고, 바로 커밋
  1. 지연 로딩(Lazy Loading)
  • 지연 로딩: 객체가 실제 사용될 때 로딩

  • 즉시 로딩: JOIN SQL로 한번에 연관된 객체까지 미리 조회

  • 데이터 접근 추상화와 벤더 독립성
profile
꾸준히 발전하는 개발자가 되자 !

0개의 댓글