깃허브 바로가기
JPA에서 가장 중요한 것은 엔티티와 테이블 매핑을 정확히 하는 것이다.
매핑 어노테이션을 잘 숙지해야 한다.
@Entity
, @Table
@Id
@Column
@ManyToOne
, @JoinColumn
JPA를 사용해서 테이블과 매핑할 클래스는 @Entity
어노테이션을 필수로 붙여야 한다.
@Entity
가 붙은 클래스는 JPA가 관리하는 것으로 엔티티라고 부른다.
속성 | 기능 | 기본값 |
---|---|---|
name | JPA에서 사용할 엔티티 이름을 정한다. 보통 기본값인 클래스 이름을 사용한다. 만약 다른 패키지에 이름이 같은 엔티티 클래스가 있다면 이름을 지정해서 충돌하지 않도록 해야 한다. | 설정하지 않으면 클래스 이름 그대로 사용 |
@Entity
적용시 주의 사항
@NoArgsConstructor
사용생성자가 하나도 없을 때 자바는 기본 생성자를 생성하지만, 생성자 오버로딩을 했을 때는 개발자가 직접 기본 생성자를 만들어줘야 한다.
@Table은 엔티티와 매핑할 테이블을 지정. 생략시 매핑한 엔티티 이름을 테이블 이름으로 사용
속성 | 기능 | 기본값 |
---|---|---|
name | 매핑할 테이블 이름 | 엔티티 이름을 사용 |
catalog | catalog 기능이 있는 DB에서 catalog매핑 | |
schema | schema 기능이 있는 DB에서 schema 매핑 | |
uniqueConstraints | DDL 생성시 유니크 제약조건을 만듦. 2개 이상의 복합 유니크 제약조건도 만들 수 있다. 스키마 자동생성기능을 사용해서 DDL을 만들때만 사용 |
@Enumerated
: 자바의 enum을 사용할 때@Temporal
: 자바의 날짜타입 매핑@LOB
: CLOB, BLOB 타입 매핑JPA는 DB스키마를 자동 생성하는 기능을 지원.
application.yaml
spring:
jpa:
hibernate:
ddl-auto: create
어플리케이션 실행 시점에 DB테이블 자동으로 생성
옵션 | 설명 |
---|---|
create | 기존 테이블을 삭제하고 새로 생성, DROP + CREATE |
create-drop | create 속성에 추가로 어플리케이션을 종료할때 DDL 제거, DROP + CREATE + DROP |
update | DB 테이블과 엔티티 매핑정보를 비교해서 변경 사항만 수정 |
validate | DB 테이블과 엔티티 매핑정보를 비교해서 차이가 있으면 경로를 남기고 어플리케이션을 실행하지 않는다. 이것은 DDL을 수정하지 않음. |
none | 자동 생성 기능을 사용하지 않으려면 ddl-auto 속성을 제거하거나 유효하지 않은 옵션 값을 주면 된다.(none은 유효하지 않은 옵션값) |
sql보기
spring:
jpa:
properties:
hibernate:
show_sql: true
@Column
매핑정보의 nullable속성 값을 false로 지정하면 자동 생성되는 DDL에 not null
제약조건을 추가할 수 있다. 자동 생성되는 DDL에 문자 크기를 length옵션으로 지정할 수 있다.
@Table
에 유니크 제약조건을 만들어주는 uniqueConstraints 속성은 유니크 제약조건을 말 그대로 걸어주는 것인데 이 속성들은 DDL을 자동 생성할때만 사용되고 JPA 실행 로직에는 영향을 주지 않는다.
직접 DDL을 만들면 사용할 이유가 없는 속성들이다.
그럼에도 이 기능을 사용한다면 엔티티만 보고도 다양한 제약조건을 파악할 수 있다는 장점이 존재
@Entity
public class Member{
@Id
@Column(name= "ID")
private String id;
JPA에서 제공하는 DB 기본키 생성 전략
자동생성 전략이 다양한 이유는 DB벤더마다 지원하는 방식이달라서 이다.
SEQUENCE나 IDENTITY 전략은 사용하는 DB에 의존
기본키를 할당하려면 @Id 사용, 자동생성 전략을 이용하려면 @GeneratedValue
를 사용하면 된다.
기본 키 생성을 DB에 위임하는 전략
MySQL, Postgre, SQL Server, DB2 에서 사용
@Id
@GeneratedValue(strategy = GenertaionType.IDENTITY)
private Long id;
IDENTITY는 데이터를 DB에 insert한 후에 기본 키 값을 조회할 수 있음.
그러므로 엔티티에 식별자 값을 할당하려면 추가로 DB를 조회해야함
유일한 값을 순서대로 생성하는 전략
Oracle, Postgre, DB2, H2 에서 사용 가능
@SequenceGenerator
에 시퀀스 생성기를 name이값에 등록하고
sequenceName 속성 이름으로 DB 시퀀스를 매핑함
그러면서
@GenerateValue(strategy = Generation.Type.SEQUENCE, generator = "SequenceGenerator의 name값"
)
사용하면 시퀀스 생성기 할당됨
@SequenceGenerator
속성 | 기능 | 기본값 |
---|---|---|
name | 식별자 생성기 이름 | 필수 |
sequenceName | DB에 등록된 시퀀스 이름 | hibernate_sequence |
initialValue | DDL 생성시에 사용, 시퀀스 DDL 생성할때 처음 시작하는 수 지정 | 1 |
allocationSize | 시퀀스 한번 호출에 증가하는수(성능최적화에 사용) | 50 |
catalog, schema | 데이터베이스 catalog, schema이름 |
DDL ex - create sequence [sequenceName] start with [initialValue] increment by [allocationSize]
키생성 전용 테이블을 하나 만들고 이름과 값으로 사용할 컬럼 만든후 시퀀스를 흉내내는 전략
create table MY_SEQUENCES {
sequence_name varchar(255) not null,
next_val bigint,
primary key (sequence_name)
}
@GeneratorValue(generator = "BOARD_SEQ_GENERATOR")
@TableGenerator
속성 | 기능 | 기본값 |
---|---|---|
name | 식별자 생성기 이름 | 필수 |
table | 키생성 테이블명 | hibernate_sequences |
pkColumnName | 시퀀스 컬럼명 | sequence_name |
valueColumnName | 시퀀스 값 컬럼명 | next_val |
pkColumnValue | 키로 사용할 값 이름 | 엔티티 이름 |
initialValue | 초기 값, 마지막으로 생성된 값이 기준 | 0 |
allocationSize | 시퀀스 한번 호출에 증가하는 수(성능 최적화) | 50 |
catalog, schema | DB catalog, schema 이름 | |
uniqueConstraints(DDL) | 유니크 제약 조건 지정 |
선택한 DB의 방언에 따라 Identity, Sequence, Table 전략중 하나 자동으로 설정
영속성 컨텍스트는 엔티티를 식별자 값으로 구분하기 때문에 엔티티를 영속 상태로 만드려면 식별자 값은 반드시 포함해야 하는 사실. em.perist()
를 호출한 직후 발생하는일을 정리하면 아래와 같다.
em.persist()
를 호출하기 전에 애플리케이션에서 직접 식별자 값 할당JPA에서 제공하는 필드와 컬럼 매핑용 어노테이션 정리
분류 | 매핑 어노테이션 | 설명 |
---|---|---|
필드와 컬럼 매핑 | ||
@Column | 컬럼을 매핑 | |
@Enumerated | 자바 enum 타입 매핑 | |
@Temporal | 날짜 타입 매핑 | |
@Lob | CLOB, BLOB 타입 매핑 | |
@Transient | 특정 필드를 DB에 매핑하지 않음 | |
기타 | @Access | JPA가 엔티티에 접근하는 방식 지정 |
속성 | 기능 | 기본값 |
---|---|---|
name | 필드와 매핑할 테이블 컬럼이름 | 객체의 필드이름 |
nullable(DDL) | null값 허용 여부 설정. false설정 시 DDL조건에 not null제약조건 추가됨 | true |
unique(DDL) | 한 컬럼에 간단히 유니크 제약조건 걸 때 사용, 두 컬럼 이상 사용시 @Table.uniqueConstraints사용 | |
ColumnDefinition(DDL) | DB 칼럼 정보 직접 줄 수 있음 | 필드의 자바 타입과 방언 정보를 사용해서 적절한 컬럼 타입 생성 |
length(DDL) | 문자 길이 제약조건, String타입에만 사용 | 255 |
precision, scale(DDL) | BigDecimal타입에서 사용 precision은 소수점 포함 전체자리수, scale은 소수 자리수, float이나 double타입에는 적용 안됨 | precision = 19, scale= 2 |
안쓰는 것은 구글링을 해서 찾아야겠다.
TemporalType필수 지정
지정할 수 있는 속성이 없음.
대신 매핑하는 필드타입이 문자라면 CLOB으로 매핑 나머지는 BLOB으로 매핑
매핑하지 않는 필드, 그렇기 때문에 DB에 저장하지도 않고 조회하지도 않음.
객체에 임시로 어떤 값을 보관하고 싶을 때 사용함.
엔티티 데이터에 접근하는 방식 지정
AccessType.FILED
로 지정.AccessType.PROPERTY
로 지정. 접근자(Getter) 사용.@Access
를 설정하지 않으면 @Id
위치를 기준으로 접근방식 설정
@Id
가 필드에 있으면 @Access(AccessType.FILED)
로 설정한 것과 같음.
그래서 생략 가능