Updated:

1. 개요

과거에는 대부분 MyBatis를 사용했지만, 최근에는 JPA로 넘어가는 추세이다. 이번에는 JPA란 무엇인지에 대해 알아보도록 하자.

2. SQL 중심적인 개발의 문제점

1) 반복되는 코드

  • 쿼리를 직접 작성해야 하고, SQL과 객체를 매핑하는 코드도 반복해서 작성해야 된다.

  • 테이블의 컬럼이 변경된 경우(추가, 삭제 등) 객체 뿐만 아니라 쿼리문도 직접 변경해야 한다.

2) 패러다임 불일치 - 상속

  • 객체는 상속 관계를 가질 수 있지만 DB는 상속의 개념이 없다.

  • 상속 관계의 객체를 테이블에 저장할 경우 INSERT 쿼리를 여러 번 날려야 한다.

  • 상속 관계의 객체를 조회할 경우에도 테이블마다 JOIN SQL을 작성해야 한다.

3) 패러다임 불일치 - 연관관계

  • 객체는 연관관계를 위해 참조를 사용하지만 테이블은 외래키를 사용한다.

4) 패러다임 불일치 - 객체 그래프 탐색

  • 객체는 자유롭게 그래프를 탐색할 수 있지만, SQL은 처음 실행하는 SQL에 따라 범위가 정해진다.

  • SQL을 통해 모든 객체를 한 번에 로딩할 수 없으므로 엔티티의 신뢰 문제가 발생한다.

5) 패러다임 불일치 - 비교

  • 같은 데이터를 두 번 조회 후 == 비교를 했을 때, 컬렉션에서 조회 시에는 항상 같은 객체가 반환되므로 true이지만, SQL 조회결과를 객체에 매핑 시에는 new로 매번 새로운 객체를 생성하므로 다른 객체로 반환되어 false가 된다.

3. JPA란?

JPA는 Java Persistence API의 약자로, 자바 진형의 ORM 기술 표준이다. 기존에 DB와 연결하기 위해 JDBC API를 직접 이용했는데, JPA가 제공해주는 인터페이스를 통해 직접 JDBC API를 이용하지 않아도 편리하게 DB와 연결이 가능하다. (JPA가 JDBC API를 대신 호출해준다.)

JPA는 표준 인터페이스이고 여러 구현체가 있는데, 구현체로 주로 하이버네이트(Hibernate)를 사용한다.

4. ORM이란?

ORM은 Object-Relational Mapping의 약자로, 이름 그대로 객체 관계 매핑을 말한다. 객체는 객체대로 설계하고, DB는 DB대로 설계한 후 ORM을 중간에서 객체와 DB를 적절하게 매핑해주는 역할을 한다.

5. JPA 특징

5-1. 1차 캐시

같은 트랜잭션에서는 동일한 쿼리 조회 시 최초 1회만 SQL을 호출 후 호출 결과를 1차 캐시에 저장하고, 두 번째 호출 시 1차 캐시의 데이터를 사용한다. 따라서 항상 같은 객체가 반환되는 것이 보장된다. 또한 DB Isolation Level이 READ COMMITTED로 설정되어 있더라도 애플리케이션에서 REPEATABLE READ가 보장된다.

1
2
3
4
5
Long id = 1L;
Member member1 = em.find(Member.class, id); // SQL 조회
Member member2 = em.find(Member.class, id); // 1차 캐시 조회

System.out.println(m1 == m2); // true

5-2. 쓰기 지연

트랜잭션을 커밋할 때까지 쓰기 쿼리를 보내지 않고, JDBC Batch SQL을 사용해서 커밋 시점에 한 번에 보낸다.

1
2
3
4
5
tx.begin();

em.persist(member1);
em.persist(member2);
tx.commit(); // 이 순간 두 개의 INSERT 쿼리 호출

5-3. 지연 로딩

관련된 객체를 한 번에 조회하는 것이 아니라, 실제로 사용하는 시점에 조회되도록 할 수 있다. 자주 함께 사용되는 데이터라면 한 번에 조회하는 것이 좋겠지만, 가끔씩만 함께 사용하는 데이터라면 사용할 때 조회해오는것이 성능상 이점이 된다.

[즉시 로딩]

1
2
3
Member member = em.find(1L); // select * from member m join team t...
Team team = member.getTeam();
String teamName = team.getName();

[지연 로딩]

1
2
3
Member member = em.find(1L); // select * from member
Team team = member.getTeam();
String teamName = team.getName(); // select * from team

출처 : 자바 ORM 표준 JPA 프로그래밍 - 기본편

Updated:

Leave a comment