참고

JPA?

  • Java Persistence API
  • 자바 진영의 ORM 기술 표준

ORM?

  • Object-relational mapping (객체 관계 매핑)
  • 객체는 객체대로 설계
  • 관계형 데이터베이스는 관계형 데이터베이스대로 설계
  • ORM 프레임워크가 중간에서 매핑
  • 대중적인 언어에는 대부분 ORM 기술이 존재
  • ex) TypeORM..

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

  • JPA 동작 - 저장
    • Entity 분석
    • INSERT SQL 생성
    • JDBC API를 사용하여 DB에 SQL 보냄
    • 패러다임 불일치 해결
  • JPA 동작 - 조회
    • DAO쪽에서 pk값을 넘김
    • JPA가 SELECT SQL 생성
    • JDBC API 사용
    • DB쪽에 SQL 보냄
    • DB쪽에서 결과를 반환하면 ResultSet 매핑
    • 그 ResultSet Entity Object를 DAO에 넘김
    • 패러다임 불일치 해결

JPA 소개

과거에도 ORM기술은 있었다. 바로 EJB라는 것인데, 문제점은 너무 아마추어적이었다.
인터페이스 구현도 많고 느리고 기본동작에도 오류가 많았었다. 그래서 어느 한 SI 개발자가
화가나서 만든 오픈소스가 하이버네이트고 이 하이버네이트를 기반으로 그대로 받아들여서 만든 자바표준이 JPA다.
또한 EJB에 이상한 컨테이너도 있었는데 너무 복잡하여 이것을 좀더 간편하게 오픈소스를 시킨 개발자가 있었는데 그 개발자 이름은 Spring의 창시자 로드존슨이고 그 컨테이너가 Spring이 되었다.

여담이지만, EJB덕분에 JPA와 Spring이 생겼으니 감사히 여겨야 할것 같다. :)

JPA는 표준 명세

  • JPA는 인테페이스의 모음
  • JPA 2.1 표준 명세를 구현한 3가지 구현체
  • Hibernate, EclipseLink, DataNucleus

JPA 버전

  • JPA 1.0(JSR 220) 2006년 : 초기 버전. 복합 키와 연관관계 기능이 부족
  • JPA 2.0(JSR 317) 2009년 : 대부분의 ORM 기능을 포함, JPA Criteria 추가
  • JPA 2.1(JSR 338) 2013년 : 스토어드 프로시저 접근, 컨버터(Converter), 엔티 티 그래프 기능이 추가

왜 JPA를 사용해야 하는가?

  • SQL 중심적인 개발에서 객체 중심으로 개발
  • 생산성
  • 유지보수
  • 패러다임의 불일치 해결
  • 성능
  • 데이터 접근 추상화와 벤더 독립성
  • 표준

생산성

  • 저장: jpa.persist(member)
  • 조회: Member member = jpa.find(memberId)
  • 수정: member.setName(“변경할 이름”)
  • 삭제: jpa.remove(member)

유지보수

  • 기존: 필드 변경시 모든 SQL 수정
  • JPA: 필드만 추가하면 되며, SQL은 JPA가 처리한다.

JPA와 패러다임의 불일치 해결

  • JPA와 상속 - 저장
    • 개발자: jpa.persist(book);
  • JPA와 상속 - 조회
    • 개발자: Book book = jpa.find(Book.class, bookId);

JPA와 연관관계, 객체 그래프 탐색

  • 연관관계 저장
member.setTeam(team);
jpa.persist(member);
  • 객체 그래프 탐색
Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam(); 

신뢰할수 있는 엔티티, 계층

class MemberService {
...
  public void process() {
    Member member = memberDAO.find(memberId);
    member.getTeam(); //자유로운 객체 그래프 탐색
    member.getOrder().getDelivery();
    }
  }

JPA와 비교하기

  • 동일한 트랜잭션에서 조회한 엔티티는 같음을 보장

JPA의 성능 최적화 기능

  • 1차 캐시와 동일성(identity) 보장
    • 같은 트랜잭션 안에서는 같은 엔티티를 반환 - 약간의 조회 성능 향상
    • DB Isolation Level이 Read Commit이어도 애플리케이션에서 Repeatable Read 보장
String memberId = "100";
Member m1 = jpa.find(Member.class, memberId); //SQL
Member m2 = jpa.find(Member.class, memberId); //캐시
println(m1 == m2) //true
  • 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)
    • 트랜잭션을 커밋할 때까지 INSERT SQL을 모음
    • JDBC BATCH SQL 기능을 사용해서 한번에 SQL 전송
    • UPDATE, DELETE로 인한 로우(ROW)락 시간 최소화
    • 트랜잭션 커밋 시 UPDATE, DELETE SQL 실행하고, 바로 커밋
transaction.begin(); // [트랜잭션] 시작
 
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 모아서 보낸다.
transaction.commit(); // [트랜잭션] 커밋
transaction.begin(); // [트랜잭션] 시작
 
changeMember(memberA);
deleteMember(memberB);
비즈니스_로직_수행(); //비즈니스 로직 수행 동안 DB 로우 락이 걸리지 않는다.
//커밋하는 순간 데이터베이스에 UPDATE, DELETE SQL을 보낸다.
transaction.commit(); // [트랜잭션] 커밋
  • 지연 로딩(Lazy Loading)
    • 지연로딩:객체가실제사용될때로딩
    • 즉시 로딩: JOIN SQL로 한번에 연관된 객체까지 미리 조회

ORM은 객체와 RDB 두 기둥위에 있는 기술이다.

마무리

JPA를 쓰면 뭐가 편해지고 어떤 기능들이 있는지 많은 것을 느꼈다. 조금은 많은 양이여서
내용이 벅차긴 했지만 하나하나 다시 새긴다는 마음으로 공부를 해나가야겠다.

profile
모든 것을 즐길줄 아는 개발자입니다!

0개의 댓글

Powered by GraphCDN, the GraphQL CDN