-> JPA를 사용하는 데 가장 중요한 일은 엔티티와 테이블을 정확히 매핑 하는 것
엔티티
는 데이터베이스나 SQL상에 존재하지 않는 일종의 개념이다. 테이블
은 데이터베이스나 SQL에 실제로 존재하고 물리적인 구조를 가지고 있다.@Entity가 붙은 클래스는 JPA가 관리하는 것으로 엔티티라 부른다.
속성 | 기능 | 기본값 |
---|---|---|
name | JPA에서 사용할 엔티티 이름을 지정한다. 보통 기본값인 클래스 이름을 사용한다. 다른 패키지에 이름이 같은 엔티티 클래스가 있다면 이름을 지정해서 충돌을 방지 | 클래스의 이름을 그대로 사용한다. |
기본 생성자는 필수(파라미터가 없는 Public
또는 protected
생성자)
final
클래스, enum
, interface
, inner
클래스에는 사용할 수 없다.
저장할 필드에 final을 사용하면 안 된다.
속성 | 기능 | 기본값 |
---|---|---|
name | 매핑할 테이블 이름 | 엔티티 이름 |
catalog | catalog 기능이 있는 데이터베이스에서 catalog를 매핑한다. | |
schema | schema 기능이 있는 데이터베이스에서 schema를 매핑한다. | |
uniqueConstraints (DDL) | DDL 생성 시 유니크 제약조건을 만든다. 복합 유니크 제약 조건도 만들 수 있다. 스키마 자동 생성 기능을 사용해서 DDL을 만들 때만 사용 |
속성 | 기능 | 기본값 |
---|---|---|
name | 필드와 매핑할 테이블의 컬럼 이름 | 객체의 필드 이름 |
nullable(DDL) | null값 허용 여부 설정 | true |
unique(DDL) | 한 컬럼에 유니크 제약조건을 걸 때 사용 두컬럼 이상에 유니크 제약조건 사용시 @Table(uniqueConstraints=)를 사용 | |
columnDefinition(DDL) | 데이터베이스 컬럼 정보를 직접 줄 수 있다. @Column(columnDefinition = "boolean default false") | 필드의 자바 타입과 방언 정보를 사용해서 적절한 컬럼 타입을 생성 |
length(DDL) | 문자 길이 제약 조건, String 타입에만 사용 | 255 |
precision, scale (DDL) | BigDecimal, BigInteger 타입에서 사용 precision : 소수점을 포함한 전체 자릿수 scale : 소수의 자릿수 => double, float타입에 적용 x, 아주 큰 숫자나 정밀한 소수를 다룰때 사용 | precision = 19 scale = 2 |
BigDecimal
: Java 언어에서 실수를 정밀하게 저장하고 표현할 수 있는 유일한 방법 (돈을 다룰 때 필수)nullable
속성 예외자바 enum 타입을 매핑할 때 사용
속성 | 기능 | 기본값 |
---|---|---|
value | - EnumType.ORDINAL : enum 순서를 DB에 저장 - EnumType.STRING : enum 이름을 DB에 저장 | EnumType.ORDINAL |
EnumType.ORDINAL
EnumType.STRING
속성 | 기능 | 기본값 |
---|---|---|
value | - TemporalType.DATE : 날짜, DB의 date 타입과 매핑 - TemporalType.TIME : 시간, DB의 time 타입과 매핑 - TemporalType.TIMESTAMP : 날짜와 시간, DB timestamp 타입과 매핑 | EnumType.ORDINAL |
BLOB
, CLOB
타입과 매핑한다.transient
: 직렬화 시 특정 멤버변수를 무시하고 싶은 경우 사용하는 키워드속성 | 기능 | 기본값 |
---|---|---|
value | - AccessType.FILED : 필드에 직접 접근한다. private 이어도 접근할 수 있다. - AccessType.PROPERTY : 접근자를 사용한다. | @Id 위치를 기준으로 설정 |
<!--하이버네이트의 HBM2DDL-->
<property name="hibernate.hbm2ddl.auto" value="속성"/>
<!--DDL 콘솔에 출력-->
<property name="hibernate.show_sql" value="true"/>
<!--JPA2.1 부터 표준으로 지원, UPDATE, VALIDATE 옵션 지원 X -->
<property name="javax.persistence.schema-genertaion.dtabase.action" value="속성"/>
JPA는 클래스의 매핑정보와 데이터베이스 방언을 사용해서 데이터베이스 스키마를 생성한다.
애플리케이션 실행 시점에 DB 테이블이 자동으로 생성되어 개발자의 수고를 덜 수 있다.
완벽하지 않으므로 개발환경에서 사용하거나 매핑을 어떻게 해야하는지 참고 정도로만 사용
속성 | 기능 |
---|---|
create | DROP + CREATE |
create-drop | DROP + CREATE + DROP |
update | DB 테이블과 엔티티 매핑정보를 비교해서 변경 사항만 수정 |
validate | DB 테이블과 엔티티 매핑정보를 비교해서 차이가 있으면 경고를 남기고 실행 X |
none | 자동 생성 기능을 사용하지 않음, 유효하지않은 옵션 값 |
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
java.util.Date
: 1970년 1월 1일 00:00:00 GMT 이후 정확한 밀리 초로 현재 순간을 알려줌java.sql.Date
: SQL 날짜에는 년, 월, 일만 포함되며 시간 및 시간대는 없음javax.persistence.PersistenceException
<property name="hibernate.id.new_generator_mappings" value="true"/>
IDENTITY : 기본 키 생성을 DB에 위임한다.
AUTO_INCREMENT
@GeneratedValue(strategy = GenerationType.IDENTITY)
persist()
호출 즉시 INSERT SQL이 DB에 전달되어 쓰기 지연이 동작하지 않는다. Statement.getGenertaedKeys()
를 사용하면 데이터 저장과 동시에 기본 키 값도 얻을 수 있음ResultSet
에 자동 생성된 키의 데이터 유형은 해당 도메인의 데이터 유형에 상관 없이 DECIMAL
이다.SEQUENCE : DB 시퀀스를 사용해서 기본 키를 할당한다. (오라클, H2)
// 시퀀스 생성
CREATE SEQUENCE BOARD_SEQ START WITH 1 INCREMENT BY 1;
// 시퀀스 매핑
@Entity
@SequenceGenerator(
name = "BOARD_SEQ_GENERATOR",
sequenceName = "BOARD_SEQ",
initialValue = 1, allocationSize = 1)
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "BOARD_SEQ_GENERATOR")
private Long id;
}
// DDL
create sequence [sequenceName] start with [initialValue] increment by [allocationSize]
사용 코드는 IDENTITY 전략과 같지만 내부 동작 방식은 다르다.
em.persist()
호출시 시퀀스를 사용해서 식별자를 조회하고, 그 식별자를 엔티티에 할당한 후에 엔티티를 영속성 컨텍스트에 저장한다.
@SequenceGenerator 속성
속성 | 기능 | 기본 값 |
---|---|---|
name | 식별자 생성기 이름 | NOT NULL ! |
sequenceName | 데이터베이스에 등록되어 잇는 시퀀스 이름 | hibernate_sequence |
initialValue | DDL 생성 시에만 사용됨. 처음 시작하는 수 | 1 |
allocationSize | 시퀀스 한 번 호출에 증가하는 수(성능 최적화에 사용) | 50 |
catalog, schema | DB catalog, schema 이름 |
TABLE : 키 생성 테이블을 사용한다.
// 키 생성 DDL
create table MY_SEQUENCES (
sequence_name varchar(255) not null,
next_val bigint,
primary key (sequence_name)
)
// 키 생성기 등록
@Entity
@TableGenerator(
name = "BOARD_SEQ_GENERATOR",
sequenceName = "MY_SEQUENCES",
pkColumnValue = "BOARD_SEQ", allocationSize = 1)
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.TABLE,
generator = "BOARD_SEQ_GENERATOR")
private Long id;
}
SELECT
쿼리를 사용하고next_val
컬럼 값을 증가시키기위해 UPDATE
쿼리를 사용한다.@TableGenerator.allocationSize
를 사용한다.GenerationType.AUTO
는 선택한 DB 방언에 따라 전략을 하나 자동으로 선택한다.