2019년 9월 17일 화요일

JPA 코드 없이 적는 기본 개념

JPA는 Java의 객체를 table/relationship에 직접 매핑해보자는 시도에서 출발한다. 이런걸 ORM이라고 한다. JPA 이전에 ORM은 이러한 프레임워크를 나타내는데 쓰이는 일반적인 용어였다.

JPA를 쓰면 애플리케이션의 클래스를 데이터베이스의 테이블에 매핑할 수 있다. (쿼리를 작성해 날리는 방식인 JPQL도 엔티티 간 매핑을 알고있는 상태에서 수행되기 때문에 SQL과 차이가 있다.) 객체 모델을 중심으로 사고할 수 있는 것이다.

JPA는 스펙이고, JPA 스펙을 구현하기 위해선 ORM 구현체(Provider)가 필요하다. 여기서 주로 쓰이는 구현체가 바로 그 Hibernate다. (Hibernate가 JPA를 위해 만들어진 것은 아니다. 특정 부분에선 JPA가 제공하는 기능 외의 기능들을 Hibernate가 제공하기도 한다.) 그리고 Hibernate 대신에 다른 JPA 구현체를 사용할 수도 있다.
 → 서블릿과 JSP가 웹 개발을 위한 자바 스펙인 것처럼, JPA는 ORM을 위한 자바 스펙인 것이다. 이와 유사하게 톰캣, 제티가 서블릿/JSP 스펙을 구현한 서버인 것처럼 Hibernate가 JPA 스펙을 구현하고 있다.

출발은 엔티티다.
데이터베이스 테이블에 저장하고 싶은 클래스 타입에 @Entity를 붙여주면, 클래스 타입에 맞는 테이블이 데이터베이스에 생성되는 방식이다. 인자없는 기본 생성자는 습관적으로 만들어주는 것이 좋다. 마지막으로 객체마다 ID를 설정해 주어야 한다. ID에 해당하는 필드엔 @Id, @GeneratedValue 어노테이션을 붙여준다.

일반적으론 JPA 조차도 쌩으로 쓰진 않는다. Spring Data JPA 라이브러리를 통하게 되는데 Spring Data JPA는 JPA를 더 쓰기 편하게 만들어 놓은 라이브러리다. JPA의 EntityManager를 직접 다루지 않고도 Spring Data JPA의 Repository를 통해 더 쉽게 데이터를 다룰 수 있게 된다.

특별한 관계를 갖지 않는 엔티티의 CRUD는 JpaRepository<T, ID>를 상속받고 @Repository 어노테이션을 붙이는 것만으로 끝이난다. 더 할게 없다. (조금만 살펴보면 JpaRepository는 PagingAndSortingRepository를 상속받고, PagingAndSortingRepository는 다시 CrudRepository를 상속받는 것을 알 수 있다.)

관계 설정도 어노테이션 방식으로 처리된다.
@OneToMany, @ManyToOne, @ManyToMany
관계 설정의 방식, mappedBy 속성의 사용 방식에 따라 조인 테이블의 생성 유무 등 테이블이 생성되는 방식이 조금씩 바뀐다.

• 자주 쓰이는 설정값
/src/main/resources/application.properties
# 세션 메트릭을 보여준다.
spring.jpa.properties.hibernate.generate_statistics=true

# 쿼리를 표시한다.
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

• 사용상 주의점
JPA가 만능은 아니다. 특정 작업에선 SQL과 비교했을 때 성능 저하가 생길 수 있다. 통계, 집계, 배치와 같은 작업은 JPA보다 SQL을 쓰는 것이 낫다고 알려져 있다.

댓글 없음:

댓글 쓰기