Chapter 2: JPA 시작
라이브러리와 프로젝트 구조
JPA 구현체로 하이버네이트를 사용하기 위한 핵심 라이브러리
hibernate-core
하이버네이트 라이브러리
hibernate-entitymanager
하이버네이트가 JPA 구현체로 동작하도록 JPA 표준을 구현한 라이브러리
hibernate-jpa-2.1-api
JPA 2.1 표준 API를 모두 모아둔 라이브러리
메이븐과 사용 라이브러리 관리
메이븐 (Maven)
라이브러리 관리 기능과 빌드 기능을 제공
라이브러리 관리 기능
메이븐은 사용할 라이브러리
이름
과버전
을 명시하면, 라이브러리를자동으로 내려받고 관리
해준다
빌드 기능
메이븐은 애플리케이션을 빌드하는 표준화된 방법을 제공한다
객체 매핑 시작
@Entity
이 클래스를 테이블과 매핑한다고 JPA에 알려준다
이렇게
@Entity
가 사용된 클래스를 엔티티 클래스라고 한다
@Table
엔티티 클래스에 매핑할 테이블 정보를 알려준다
이 어노테이션을 생략하면 클래스 이름으로 매핑한다
정확히는 엔티티 이름을 사용한다
@Id
엔티티 클래스의 필드를 기본 키(Primary Key) 에 매핑한다
@Id
가 사용된 필드를 식별자 필드라 한다
@Column
필드를 컬럼에 매핑한다
매핑 정보가 없는 필드
매핑 어노테이션을 생략하면 필드명을 사용해서 컬럼명으로 매핑한다
persistence.xml
설정
persistence.xml
설정JPA는 persistence.xml을 사용해서 필요한 설정 정보를 관리한다
해당 파일이
META-INF/persistence.xml
class path 경로에 있으면 별도 설정 없이 JPA가 인식할 수 있다
JPA 설정은
영속성 유닛 (persistence-unit)
이라는 것부터 시작하는데, 일반적으로 연결 할 데이터베이스 당 하나의 영속성 유닛을 등록한다영속성 유닛에는 고유한 이름을 부여해야 한다
이름이
javax.persistence
로 시작하는 속성은JPA 표준 속성
으로 특성 구현체에 종속되지 않는다반면
hibernate
로 시작하는 속성은하이버네이트 전용 속성
이므로 하이버네이트에서만 사용할 수 있다
데이터베이스 방언
JPA는 특정 데이터베이스에 종속적이지 않은 기술이라서 다른 데이터베이스로 손쉽게 교체할 수 있다
but, 각 데이터베이스가 제공하는 SQL 문법과 함수가 조금씩 다르다는 문제점이 있다
데이터베이스마다 갖고있는 차이점 예시
데이터 타입
가변 문자 타입으로 MySQL은
VARCHAR
, 오라클은VARCHAR2
를 사용한다
다른 함수명
문자열을 자르는 함수로 SQL 표준은
SUBSTRING()
을 사용하지만, 오라클은SUBSTR()
을 사용한다
페이징 처리
MySQL은
LIMIT
을 상요하지만, 오라클은ROWNUM
을 사용한다
이처럼 SQL 표준을 지키지 않거나, 특정 데이터베이스만의 고유한 기능을 JPA에서는
방언 (Dialect)
이라 한다하이버네이트를 포함한 대부분의 JPA 구현체들은 이런 문제를 해결하기위해 다양한 데이터베이스 방언 클래스를 제공한다
개발자는 JPA가 제공하는 표준 문법에 맞추어 JPA를 사용하면 되고, 특정 데이터베이스에 의존적인 SQL은 데이터베이스 방언이 처리해준다
하이버네이트 전용 속성
hibernate.show_sql
하이버네이트가 실행한 SQL을 출력한다
hibernate.format_sql
하이버네이트가 실행한 SQL을 출력할 때 보기 쉽게 정렬한다
hiberante.use_sql_comments
쿼리를 출력할 때 주석도 함께 출력한다
hibernate.id.new_generator_mappings
JPA 표준에 맞춘 새로운 키 생성 전략을 사용한다
엔티티 매니저 설정
엔티티 매니저 생성 과정 분석
엔티티 매니저 팩토리 생성
JPA를 시작하려면 우선 persistence.xml의 설정 정보를 사용해서
엔티티 매니저 팩토리
를 생성해야 한다이때
Persistence
class를 사용하는데 이 클래스는 엔티티 매니저 팩토리를 생성해서 JPA를 사용할 수 있게 준비한다
persistence.xml의 설정 정보를 읽어서 JPA를 동작시키기 위한 기반 객체를 만들고, JPA 구현체에 따라서는 데이터베이스
커넥션 풀
도 생성하므로 엔티티 매니저 팩토리를 생성하는 비용은 아주 크다따라서 엔티티 매니저 팩토리는 애플리케이션 전체에서
딱 한 번만 생성
하고공유
해서 사용해야 한다
엔티티 매니저 생성
엔티티 매니저 팩토리에서 엔티티 매니저를 생성한다
JPA의 기능 대부분은
엔티티 매니저
가 제공한다대표적으로 엔티티 메니저를 사용해서 엔티티를 데이터베이스에 등록/수정/삭제/조회할 수 있다
엔티티 매니저는 내부에 데이터소스 (데이터베이스 커넥션) 를 유지하면서 데이터베이스와 통신한다
엔티티 매니저는 데이터베이스 커넥션과 밀접한 관계가 있으므로
스레드 간
에공유
하거나재사용
하면 안 된다
종료
사용이 끝난
엔티티 매니저
는 반드시종료
해야 한다애플리케이션을 종료할 때
엔티티 매니저 팩토리
도종료
해야 한다
트랜잭션 관리
JPA를 사용하면 항상
트랜잭션 안
에서데이터를 변경
해야 한다트랜잭션 없이 데이터를 변경하면 예외가 발생한다
트랜잭션을 시작하려면 엔티티 매니저에서
트랜잭션 API
를 받아와야 한다트랜잭션 API를 사용해서 비즈니스 로직이 정상 동작하면 트랜잭션을
커밋
하고, 예외가 발생하면 트랜잭션을롤백
한다
비즈니스 로직
등록, 수정, 삭제, 조회 작업은 엔티티 매니저(em)를 통해서 수행된다
등록
엔티티를 저장하려면 엔티티 매니저의
persist()
method에 저장할 엔티티를 넘겨주면 된다JPA는 INSERT SQL을 만들어 데이터베이스에 전달한다
수정
엔티티를 수정한 후에 수정 내용을 반영하려면 em.update() 같은 method를 호출해야 할 것 같은데, 단순히 엔티티의 값만 변경한다
why?
JPA는 어떤 엔티티가 변경되었는지 추적하는 기능을 갖추고 있다
따라서 엔티티의 값만 변경하면 UPDATE SQL을 생성해서 데이터베이스에 값을 변경한다
삭제
엔티티를 삭제하려면 엔티티 매니저의
remove()
method에 삭제하려는 엔티티를 넘겨준다JPA는 DELETE SQL을 생성해서 실행한다
한 건 조회
find()
method는 조회할 엔티티 타입과@Id
로 데이터베이스 테이블의 기본 키와 매핑한 식별자 값으로 엔티티 하나를 조회하는 가장 단순한 조회 method다이 method를 호출하면 SELECT SQL을 생성해서 데이터베이스에 결과를 조회한다
그리고 조회한 결과 값으로 엔티티를 생성해서 반환한다
JPQL
애플리케이션이 필요한 데이터만 데이터베이스에서 불러오려면 결국
검색 조건
이 포함된 SQL을 사용해야 한다JPA는
JPQL (Java Persistence Query Language)
라는 쿼리 언어로 이런 문제를 해결한다
JPA는 SQL을 추상화한
JPQL
이라는 객체지향 쿼리 언어를 제공한다JPQL은 SQL과 문법이 거의 유사해서 SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 등을 사용할 수 있다
JPQL과 SQL의 차이점
JPQL은
엔티티 객체
를 대상으로 쿼리한다즉, 클래스와 필드를 대상으로 쿼리한다
SQL은
데이터베이스 테이블
을 대상으로 쿼리한다
JPQL은 데이터베이스 테이블을 전혀 알지 못한다
JPA는 JPQL을 분석해서 적절한 SQL을 만들어 데이터베이스에서 데이터를 조회한다
Last updated