목차
JPA란?
Java Persistence API
자바 진영의 ORM 기술 표준
JPA VS Mybatis
JPA를 왜 사용해야 하는가?
객체 중심 + 생산성
생산성 비교
유지보수
패러다임 불일치 해결
성능
자바 ORM 표준
- 하이버네이트는 40가지 이상의 데이터베이스 방언 지원
영속성 컨텍스트
- JPA를 이해하는데 가장 중요한 단어
- “엔티티를 영구 저장하는 환경” 이라는 뜻
- EntityManager를 통해서 영속성 컨텍스트에 접근
엔티티의 생명주기
- 비영속(new/transient)
- 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
- 영속(managed)
- 영속성 컨텍스트에 관리되는 상태
- 준영속(detached)
- 영속성 컨텍스트에 저장되었다가 분리된 상태
- 삭제(removed)
- 삭제된 상태
- 삭제된 상태
영속성 컨텍스트 장점
- 1차 캐시
- 동일성(identity) 보장
- 트랜잭션을 지원하는 쓰기(transactional-write-behind)
- 변경 감지(Dirty Checking)
- 지연 로딩(Lazy Loading)
엔티티 매핑
- 객체와 테이블 매핑 : @Entity, @Table
- 필드와 컬럼 매핑 : @Column
- 기본 키 매핑 : @Id, @GeneratedValue
- 연관관계 매핑 : @ManyToOne…, @JoinColumn
- 기타 매핑 : @Temporal, @Enumerated, @Lob, @Transient
@Entity
- @Entity가 붙은 클래스는 JPA가 관리, 엔티티라 한다.
- JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 필수
- 기본 생성자 필수(파라미터가 없는 public 또는 protected 생성자)
@Table
- @Table은 엔티티와 매핑할 테이블 지정
속성 | 설명 | 기본값 |
---|---|---|
name | 매핑할 테이블 이름 | 엔티티 이름을 사용 |
catalog | 데이터베이스 catalog 매핑 | |
schema | 데이터베이스 schema 매핑 | |
uniqueConstraints(DDL) | DDL 생성 시에 유니크 제약 조건 생성 |
Column
속성 | 설명 | 기본값 |
---|---|---|
name | 필드와 매핑할 테이블 컬럼 이름 | 객체의 필드 이름 |
insertable, updatable | 등록, 변경 가능 여부 | true |
nullable(DDL) | null 값의 허용 여부를 설정한다. false로 설정하면 DDL 생성시에 not null 제약조건이 붙는다. | |
columnDefinition(DDL) | 데이터베이스 컬럼 정보를 직접 줄 수 있다. ex)varchar(100) default ‘EMPTY’ | 필드의 자바 타입과 방언 정보를 사용해 기본값 설정 |
length(DDL) | 문자 길이 제약조건, String 타입에만 사용한다. | 255 |
precision, scale(DDL) | BigDecimal 타입에서 사용한다(BigInteger도 사용할 수 있다). precision은 소수점을 포함한 전체 자릿수를, scale은 소수의 자릿수다. 참고로 double, float 타입에는 적용되지 않는다. 아주 큰 숫자나 정밀한 소수를 다루어야 할 떄만 사용한다. | precision=19, scale=2 |
@Id, @GenaratedValue
- @Id : 직접할당 방식(필수)
- @GeneratedValue : 자동생성방식(선택)
- IDENTITY : 데이터베이스 위임(auto increment), MYSQL
- SEQUENCE : 데이터베이스 시퀀스 오브젝트 사용, ORACLE
- @SequenceGenerator 필요
- TABLE : 키 생성용 테이블 사용, 모든 DB에서 사용
- @TableGenerator 필요
- AUTO : 방언에 따라 자동 지정, 기본값
@Enumerated
- 자바 enum 타입을 매핑할 때 사용
- 주의! ORDINAL 사용 X
속성 | 설명 | 기본값 |
---|---|---|
value | - EnumType.ORDINAL : enum 순서를 데이터베이스에 저장 - EnumType.STRING : enum 이름을 데이터베이스에 저장 |
@Temporal
- 날짜 타입(java.util.Date, java.util.Calender)을 매핑할 때 사용
- 참고 : LocalDate, LocalDateTime을 사용할 때는 생략 가능(최신 하이버네이트 지원)
속성 | 설명 | 기본값 |
---|---|---|
value | - TemporalType.DATE : 날짜, 데이터베이스 date 타입과 매핑(예: 2013-10-11) - TemporalType.TIME : 시간, 데이터베이스 time 타입과 매핑(예:11:11:11) - TemporalType.TIMESTAMP : 날짜와 시간, 데이터베이스 timestamp 타입과 매핑(예: 2013-10-11 11:11:11) |
@Lob
- 데이터베이스 BLOB, CLOB 타입과 매핑
- 매핑하는 필드 타입이 문자면 CLOB매핑, 나머지는 BLOB 매핑
- CLOB : String, char[], java.sql.CLOB
- BLOB : byte[], java.sql.BLOB
@Transient
- 필드 매핑 X
- 데이터베이스 저장X, 조회X
- 주로 메모리상에서만 임시로 어떤 값을 보관하고 싶을 때 사용
@Transient
private Integer temp;
연관관계 매핑
용어 이해
- 방향(Direction) : 단방향, 양방향
- 다중성(Multiplicity) : 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M) 이해
- 연관관계의 주인(Owner) : 객체 양방향 연관관계는 관리 주인이 필요
단방향 연관관계
- 테이블은 외래 키로 조인을 사용해서 연관된 테이블을 찾는다.
- 객체는 참조를 사용해서 연관된 객체를 찾는다.
- 객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력관계를 만들 수 없다.
양방향 연관관계와 연관관계 주인
양방향 매핑 규칙
- 객체의 두 관계중 하나를 주인으로 지정
- 연관관계의 주인만이 외래 키를 관리(등록, 수정)
- 주인이 아닌쪽은 읽기만 가능
- 주인은 mappedBy 속성 사용X
- 주인이 아니면 mappedBy 속성으로 주인 지정
- 외래 키가 있는 곳을 주인으로 정해라
다대일 [N:1]
- 가장 많이 사용되는 연관관계
- 다대일의 반대는 일대다
- 항상 다(N) 쪽에 외래키가 있음
- 외래 키가 있는 곳을 주인으로 정해라
일대일 [1:1]
- 일대일 관계는 그 반대도 일대일
- 주 테이블이나 대상 테이블 중에 외래 키 선택 가능
다대다 [N:M]
- 편리해 보이지만 실무에서는 사용X
- 관계형 데이터베이스에서는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없음
- 연결 테이블을 추가해서 일대다, 다대일 관계로 풀어내야함
부록
ORM이란?
- Object-relational mapping(객체 관계 매핑)
- 객체는 객체대로 설계
- 관계형 데이터베이스는 관계형 데이터베이스대로 설계
- ORM 프레임워크가 중간에서 매핑
- 대중적인 언어에는 대부분 ORM 기술이 존재