Hayden's Archive

[JPA] 자바 ORM 표준 JPA 프로그래밍 1장 본문

Study/Java & Kotlin

[JPA] 자바 ORM 표준 JPA 프로그래밍 1장

_hayden 2022. 4. 12. 23:44

JPA는 이제껏 맛보기 수준으로만 경험해봤는데 그때그때 구글링으로만 얕은 지식을 쌓는 것은 한계가 있다고 느꼈다. 백기선님도 JPA를 쓸 거면 제대로 공부하고 써야 효과를 볼 수 있고 공부 안 하고 대충 구글링만 해서 쓸 거면 차라리 안 쓰느니만 못하다고 하셨음...( https://youtu.be/brE0tYOV9jQ

JPA 공부해야지 계속 생각만 하고 있다가 이번에 사내 스터디를 통해 김영한님의 책으로 JPA 공부를 시작하게 되었다. 책의 두께를 보니 만만치 않겠다 싶지만... 스터디의 장점을 살려 약속한 분량을 꾸준히 읽다 보면 완독을 하게 될테니 조금씩 시간을 내서 꾸준히 읽어봐야겠다.

이건 내가 보려고 정리해두는 기록~!

 

도입

  • JPA는 크게 ①테이블을 어떻게 매핑해야 하는지에 관한 설계 부분과 ②설계한 모델을 실제로 사용하는 부분으로 나뉘어짐

 

1장

  • SQL을 직접 다룰 때 발생하는 문제점
    • 코드의 반복
      • 객체 구조 ≠ 데이터 중심의 구조
        • 개발자가 객체지향 애플리케이션과 데이터베이스 중간에서 SQL, JDBC API를 사용해서 변환 작업을 직접 해줘야 함
        • 결국 CRUD 과정에서 너무 많은 SQL과 JDBC API를 작성하게 됨
    • SQL에 의존적인 개발
      • 엔티티 : 비즈니스 요구사항을 모델링한 객체
      • 물리적으로는 SQL과 JDBC API를 데이터 접근 계층에 숨기더라도 논리적으로는 엔티티와 강한 의존관계를 가짐 → 진정한 의미의 계층 분할이 어려움, 엔티티를 신뢰할 수 없음
      • 필드 하나를 추가할 때 CRUD 코드와 SQL을 대부분 변경해야 함
      • SQL 매퍼가 지루하게 반복되는 JDBC API 사용과 응답 결과를 객체로 매핑하는 일을 대신 처리해주긴 하지만, 결국 개발자가 SQL을 직접 작성해야 하고 SQL에 의존하는 개발을 하게 됨
    • JPA와 문제 해결
      • 개발자가 직접 SQL을 작성X, JPA가 제공하는 API 사용
      • JPA가 개발자 대신 적절한 SQL을 생성해서 데이터베이스에 전달
  • 패러다임의 불일치
    • 객체지향 프로그래밍 : 추상화, 캡슐화, 정보은닉, 상속, 다형성 등 시스템의 복잡성을 제어할 수 있는 다양한 장치들을 제공
    • 애플리케이션은 객체지향 언어로 개발 ↔ 데이터는 관계형 데이터베이스에 저장
      • 개발자가 중간에서 이런 불일치를 해결하는 데 리소스가 많이 듦
    • ① 객체는 상속○, 테이블은 상속X
      • PostgreSQL 같이 상속 기능을 지원하는 DB도 있으나 객체의 상속과 약간 다름
      • 상속받는 자식 객체를 DB에 저장하려면, 부모 객체에서 부모 데이터만 꺼내서 INSERT문 → 자식 객체에서 자식 데이터만 꺼내서 INSERT문
      • JPA에서는 자바 컬렉션에 객체를 저장하듯이 JPA에게 객체를 저장하면 됨
    • ② 연관관계 : 객체는 참조 사용, 테이블은 외래키 사용
      • 객체는 참조가 있는 방향으로만 조회
        • Member의 필드로 Team이 있을 때 Member가 Team을 조회할 수 있지만 반대는 불가능
      • 테이블은 외래키 하나로 모두 조인 가능
        • member JOIN team과 team JOIN member 모두 가능
      • 외래 키가 필요 없고 참조만 있으면 되는 객체 모델과 참조가 필요 없고 외래 키만 있으면 되는 테이블
        • 개발자가 중간에서 변환 역할을 해야 함
        • JPA를 사용하면 개발자가 Member와 Team의 관계를 설정하고 Member 객체를 저장하기만 하면 됨.
          • JPA가 TEAM의 참조를 외래 키로 변환해서 적절한 INSERT SQL을 데이터베이스에 전달
          • JPA가 객체 조회시 외래 키를 참조로 변환하는 일도 해줌
    • ③ 객체 그래프 탐색 : 참조를 사용해서 연관된 객체를 찾음 (ex : member.getOrder().getOrderItem()... )
      • SQL을 직접 다루면 처음 실행하는 SQL에 따라 객체 그래프를 어디까지 탐색할 수 있는지 정해져서 마음껏 객체 그래프를 탐색할 수 없음
        • Member와 Team만 있는 SQL이라면 member.getOrder()가 NULL이 됨
        • memberDAO.getMember(), memberDAO.getMemberWithTeam(), memerDAO.getMemberWithOrderWithDelivery() 등의 메서드가 모두 필요하게 됨
      • JPA를 사용하면 객체 그래프를 마음껏 탐색하는 것이 가능
        • 연관된 객체를 사용하는 시점에 적절한 SELECT SQL을 실행
        • 지연 로딩 : 실제 객체를 사용하는 시점까지 데이터베이스 조회를 미룸
          • JPA는 연관된 객체를 즉시 함께 조회할지, 실제 사용되는 시점에 지연해서 조회할지 정의 가능
    • ④ 비교 : 데이터베이스는 기본키의 값으로 row를 비교, 객체는 동일성 비교와 동등성 비교
      • 동일성(identify) 비교 : == 비교. 객체 인스턴스의 주소값 비교
      • 동등성(equality) 비교 : equals() 메서드 사용. 객체 내부의 값 비교
      • 데이터베이스의 같은 row를 조회했지만 객체의 동일성 비교에는 실패할 수 있음
        • 같은 기본 키 값 memberId로 조회하더라도 member1과 member2는 동등성은 같지만 동일성은 다름.
      • 이에 반해 JPA는 같은 트랜잭션일 때 같은 객체가 조회되는 것을 보장함
  • JPA (Java Persistence API)
    • 자바 진영의 ORM 기술에 대한 API 표준 명세
      • ORM (Object-Relational Mapping)
        • 객체와 관계형 데이터베이스를 매핑
      • 객체와 테이블을 매핑해서 패러다임의 불일치 문제를 개발자 대신 해결
        • 객체를 데이터베이스에 저장할 때 개발자는 객체를 자바 컬렉션에 저장하듯이 ORM 프레임워크에 저장
        • 조회할 때도 JPA를 통해 객체를 직접 조회
        • 개발자는 데이터 중심인 관계형 데이터베이스를 사용해도 객체지향 애플리케이션 개발에 집중할 수 있음
      • 하이버네이트(Hibernate) : 자바 진영의 다양한 ORM 프레임워크 중 하나
    • JPA는 인터페이스를 모아둔 것이고, JPA를 사용하기 위해 JPA를 구현한 ORM 프레임워크(Hibernate, EclipseLink, DataNucleus 등)를 선택해야 함
    • JPA라는 표준(일반적이고 공통적인 기능의 모음)이 있어서 특정 구현 기술에 대한 의존도를 줄일 수 있고 다른 구현 기술로 손쉽게 이동 가능
  • JPA의 강점
    • 생산성 : 지루하고 반복적인 코드와 CRUD용 SQL을 개발자가 직접 작성하지 않아도 됨
    • 유지보수 : 변경이 생기더라도 SQL과 JDBC API 코드를 개발자 대신 처리해줌
    • 상속, 연관관계, 객체 그래프 탐색, 비교하기와 같은 패러다임의 불일치 문제 해결
    • 성능
      • 같은 트랜잭션 안에서 조회시 SELECT SQL을 한번만 데이터베이스에 전달하고 두 번째는 조회한 객체를 재사용
      • 하이버네이트는 SQL 힌트를 넣을 수 있는 기능도 제공
    • 데이터 접근 추상화와 벤더 독립성
      • 애플리케이션과 데이터베이스 사이에 추상화된 데이터 접근 계층 제공 
      • 벤더마다 사용법이 다르더라도 데이터베이스를 변경할 때 JPA에게 다른 데이터베이스를 사용한다고 알려주기만 하면 됨
    • 표준 : 표준을 사용하면 다른 구현 기술로 손쉽게 변경 가능
  • JPA는 통계 쿼리 같이 복잡한 쿼리보다는 실시간 처리용 쿼리에 더 최적화
    • 복잡한 통계 쿼리는 JPA가 제공하는 네이티브 SQL을 사용하거나 SQL 매퍼 형태의 프레임워크 혼용