공부/JPA

JPA 소개

데부한 2022. 6. 28. 19:07
반응형

출처 : 자바 ORM 표준 JPA 프로그래밍 인프런 강의

 

JPA 게시글은 대부분 인프런의 김영한님의 강의인 '자바 ORM 표준 JPA 프로그래밍' 기반으로 내용을 정리했습니다.

 

JPA 소개

JPA란?

  • Java Persistence API의 줄임말이다.
  • 자바 진영의 ORM 기술 표준이다.
    • Object-relational mapping(객체 관계 매핑)
    • 객체는 객체대로 설계
    • 관계형 데이터베이스는 관계형 데이터베이스대로 설계한다.
    • ORM 프레임워크가 중간에서 매핑
    • 대중적인 언어에서는 대부분 ORM 기술이 존재한다.

 

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

  • 동작 과정
    • JAVA 애플리케이션에서 JPA API 호출
    • JPA는 JDBC API 호출
    • JDBC는 SQL 생성 또는 실행
    • DB에서 결과를 반환 받음

 

JPA 동작 - 저장

이 동작 과정에서 제일 중요한 부분은 패러다임 불일치 해결 부분이다. 중요한 내용이므로 따로 후술한다. INSERT SQL은 개발자가 직접 작성하는게 아니고 JPA에서 작성해서 DB에게 명령을 내린다.

 

JPA 동작 - 조회

 

JPA는 표준 명세

  • JPA는 인터페이스의 모음이다.
  • JPA 2.1 표준 명세를 구현한 3가지 구현체
    • 하이버네이트, EclipseLink, DataNucleus
    • 대부분 하이버네이트를 많이 사용한다.

 

왜 JPA를 사용해야 할까?

  • 생산성
    • 저장 : jpa.persist(객체);
    • 조회 : 객체 = jap.find(조회할 아이디);
    • 수정 : 객체.setXXX("변경할 내용");
      수정의 경우는 위의 코드만 작성해도 알아서 update 쿼리를 DB에 보낸다.
    • 삭제 : jpa.remove(객체);
  • 유지보수
    • 기존에 사용하던 방법으로 필드 변경이 일어나면 모든 SQL을 직접 수정해주어야한다.
    • JPA를 사용하면(DB에 추가되거나 수정 된 컬럼이 있을 시) 클래스 필드만 추가해주면 SQL은 JPA가 처리해서 따로 SQL을 수정하거나 하는 번거로운 작업이 없어진다.
  • 패러다임의 불일치 해결
    • 상속
      • DB에서 객체 상속이 이루어진 테이블을 하나 저장할 때 원래대로라면 부모 테이블과 자식 테이블(명칭이 정확하진 않다.)을 따로따로 SQL문을 작성했어야하는데 JPA에서는 jpa.persist(자식테이블);만 적어주면 알아서 부모 테이블, 자식 테이블 INSERT 쿼리문을 두 개로 나누어 처리한다.
      • 조회도 마찬가지로 자식 테이블을 조회할 경우 JPA에서 알아서 부모와 자식을 JOIN해 SELECT 처리를 해준다.
    • 연관관계, 객체 그래프 탐색
      • 신뢰할 수 있는 엔티티, 계층
    • 비교하기
      • 자바 컬렉션과 같이 동일한 객체를 두 번 조회해서 이 둘을 비교하면 같다고 나온다.
      • member1 == member2; // (동일한 아이디로 조회해서 객체를 가져왔을 경우) 같다.
      • 즉, 동일한 트랜잭션에서 조회한 엔티티는 같음을 보장한다.
  • 성능
    • 1차 캐시와 동일성(identity) 보장
      • 같은 트랜잭션 안에서는 같은 엔티티를 반환한다. -> 사실상 아주 짧은 시간의 캐싱이라 약간의 조회 성능이 향상된다.
    • DB Isolation Level이 Read Commit이어도 애플리케이션에서 Repeatable Read 보장
    • 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)
      • INSERT
        • 트랜잭션을 커밋할 때까지 INSERT SQL을 모음
        • JDBC BATCH SQL 기능을 사용해서 한번에 SQL 전송
          • transaction.begin() ~ transaction.commit(); 
    • 지연 로딩(Lazy Loading)
      • 지연 로딩 : 객체가 실제 사용될 때 로딩
        • 만약 A와 B 테이블이 외래키로 관계가 맺어져있을 경우 A만 조회했을 때 A 테이블 값만 조회하고, A와 연관된 B 테이블의 값을 꺼내오려할 때 그제서야 B 테이블에 있는 값을 조회해서 가져온다.
        • A a = aDAO.find(aId);  --> SELECT * FROM A
          B b = a.getB();
          String resultB = b.getB(); --> SELECT * FROM B
      • 즉시 로딩 : JOIN SQL로 한번에 연관된 객체까지 미리 조회한다.
        • A와 B 테이블을 JOIN한 SELECT 결과를 반환한다.
  • 데이터 접근 추상화와 벤더 독립성
  • 표준

 

반응형