출처
본 글은 인프런의 김영한님 강의 자바 ORM 표준 JPA 프로그래밍 - 기본편
을 수강하며 기록한 필기 내용을 정리한 글입니다.
-> 인프런
-> 자바 ORM 표준 JPA 프로그래밍 - 기본편 강의
요약
- JPA와 DB를 매핑시키기 위해 Annotation이 활용된다.
- 기본적인 Annotation은 다음과 같다.
-> @Entity, @Table, @Id, @GeneratedValue, @Column, @Enumerated, @Temporal, @Lob, @Transient
1. 엔티티 매핑
- JPA는 DB 테이블을 객체마냥 사용할 수 있도록 많은 도움을 준다.
- 이런 도움들을 받기 위해서는 JPA 프로젝트 내에 DB 테이블과 연결되는 클래스를 만들고, 이를 DB와 연결시키는 과정(≒ 매핑)이 필요하다.
- 이는 곧, 다음과 같이 Java 클래스와 DB 테이블을 호환시키는 과정이라고 생각하면 편하다.
-> Java에서 만든 클래스 ≒ DB 테이블
-> 해당 클래스의 멤버변수 ≒ DB 테이블의 각 Column들
-> Annotation : 연결해 주는 역할(매핑), 필요에 맞게 (요구사항에 맞추어) 호환시키기
2. 기본 Annotation 정리
- Annotation은 JPA 엔티티와 DB 테이블을 매핑시키는데 필요한 도구이다.
- Annotation 내 여러가지 속성들을 활용해 요구사항을 맞출 수 있으며, DDL 자동 생성 기능과 관련된 속성도 있다.
-> DDL 자동 생성 기능
<@Entity>
@Entity
public class Cookie{
~~
- 해당 Annotation을 붙이면 JPA에서 하나의 엔티티로 간주하고 관리해준다.
- JPA로 DB 테이블과 매핑할 클래스는 꼭 붙여주어야 한다.
- 기본 생성자를 만들어야 하며, final, enum, interface, inner 클래스에는 활용할 수 없다.
- 클래스 내 필드에 final을 붙일 수 없다.
@Entity(name = "COOKIES")
public class Cookie{
~~
- name 속성을 통해 엔티티 이름을 설정할 수 있으며, 아무런 속성을 붙이지 않으면 클래스 이름으로 설정된다.
<@Table>
@Entity
@Table(name = "CKS")
public class Cookie{
~~
- 엔티티와 매핑할 테이블을 지정한다. 위 예시의 경우, DB의 테이블들 중, "CKS" 라는 이름의 테이블과 매핑된다.
- 아무런 속성도 부여하지 않거나, @Table Annotation 자체를 쓰지 않으면 클래스 이름과 동일한 테이블과 매핑된다.
@Entity
@Table(uniqueConstraints = {@UniqueConstraints( name = "NAME_UNIQUE", columnNames = {"NAME"})})
public class Cookie{
~~
- 위 예시와 같이 'uniqueConstraints' 속성을 통해 unique 제약조건을 설정해 줄 수 있다.
<@Id>
@Entity
public class Cookie{
@Id
private Long id;
~~
- Primary Key Column과 매핑하는 Annotation이다.
<@Column>
@Column(name = "name")
private String cookieName;
~~
- Column과 매핑하는 Annotation이다. 속성 내용은 아래와 같다.
(속성)
- name : 매핑하고자 하는 Column의 이름. Default : 변수 이름 그대로.
- insertable, updatable : 해당 Column 내용을 DB에 반영할지 여부를 결정한다. Default : TRUE
- nullable (DDL) : DDL 자동 생성 시, null 값 허용 여부 결정. Default : TRUE
-> false로 설정하면 DDL 생성할 때 not null이 붙는다.
- unique (DDL) : DDL 자동 생성 시, unique 제약조건 설정. Default : False
-> 하지만 해당 속성을 이용하면 제약조건 이름을 설정할 수 없으므로, 앞서 언급한 @Table Annotation의 'uniqueConstraints' 속성을 활용하는게 더 좋다.
- columnDefinition (DDL) : DDL 자동 생성 시, DB Column 정보를 직접 정의할 수 있다.
@Column(columnDefinition = "varchar(100) default 'empty'")
- length (DDL) : DDL 자동 생성 시, String 타입에 한해 문자 길이 제약 조건을 설정한다. Default : 255
- precision, scale (DDL) : BigDecimal, BigInteger 타입에서 자릿수를 설정한다.
-> precision : 소수점 포함 전체 자릿수 설정. Default : 19
-> scale : 소수의 자릿수. Default : 2
<@Enumerated>
@Enumerated(EnumType.STRING)
private CookieTaste taste;
public enum CookieTaste{
Chocolate, Vanilla
}
- Java의 enum타입을 매핑할 때 사용된다.
(속성)
- EnumType.ORDINAL : 인덱스를 DB에 저장한다. Default.
-> 위 예시로 보면 Chocolate(0), Vanilla(1) 로, 0과 1이 각각 저장된다.
- EnumType.STRING : 이름을 DB에 저장한다.
-> Chocolate, Vanilla 글자 그대로 저장된다.
- EnumType.ORDINAL보다는 EnumType.STRING을 활용하는게 더 좋다.
(EnumType.ORDINAL 사용 시 문제점)
- 만약 위 예시에서 'Chocolate' 앞에 'Mango'를 추가할 경우, 인덱스가 다시 지정된다. : Mango(0), Chocolate(1), Vanilla(2)
- 이후에 'Mango'를 DB에 넣으면 'Mango'도 0 값을, 추가하기 전에 DB에 넣어놨던 'Chocolate'도 0 값을 갖게 된다.
- enum에 추가할 때마다 DB에 저장된 데이터 전체를 바꿀 순 없으므로 웬만하면 EnumType.STRING 을 적용하는게 맘 편하다.
<@Lob>
@Lob
private String description;
- DB에 VARCHAR보다 큰 내용을 넣고 싶을 경우, 활용된다.
- DB의 'CLOB', 'BLOB'과 매핑된다.
CLOB? BLOB?
- DB에 사이즈가 큰 데이터를 저장하기 위한 타입.
- CLOB : 문자열 데이터
- BLOB : 바이너리 데이터
<@Transient>
@Transitent
private String temp;
- 매핑을 원하지 않을 경우, 본 Annotation을 활용하면 된다.
- 해당 필드는 DB에 반영되지 않고, JPA 내에서만 활용되는 멤버변수가 된다.