JPA를 사용해 테이블과 매핑할 클래스에 붙여주는 어노테이션
-> 이를 붙임으로서 JPA에서 해당 클래스를 관리
name
: JPA에서 사용할 엔티티 이름을 지정, Default 값으론 클래스 이름을 엔티티 이름으로 지정
@Entity(name = "user2")
public class User {}
기본 생성자가 꼭 필요
final, enum, interface, innter class에서는 사용 불가
필드(변수)를 final로 선언 불가
엔티티와 매핑할 테이블을 지정
name
: 매핑할 테이블의 이름, 생략시 @Entity(name = " ")의 값을 사용
catalog
: catalog 기능이 있는 DB에서 catalog 매핑
schema
: schema 기능이 있는 DB에서 schema 매핑
uniqueConstraints
: DDL 생성 시 유니크 제약조건 생성
-> 스키마 자동 생성 기능을 사용해 DDL을 만들때만 사용
indexes
: 테이블 인덱스 지정
@Entity
@Table(name = "user3")
@Getter
@Setter
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
}
특정 속성을 기본키로 설정하는 어노테이션
JPA 엔티티 객체의 식별자로 사용할 필드
에 적용하며, 유니크한 DB의 컬럼과 맵핑하는것이 보통
@Entity(name="user2")
@Table
@Getter
@Setter
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
}
@Id 어노테이션만 붙이면 기본키는 직접 부여해야함
-> 보통 DB 설계시에는 자동 부여 되게끔 함(@GeneratedValue)
생성 전략엔 크게 IDENTITY, SEQUENCE, TABLE이 있다
IDENTITY
: 기본키 생성을 DB에 위임(Mysql)
SEQUENCE
: DB 시퀀스를 사용해서 기본 키 할당(ORACLE)
TABLE
: 키 생성 테이블 사용(모든 DB 사용 가능)
AUTO
: 선택된 DB에 따라 자동으로 전략 선택
객체의 필드를 테이블 컬럼과 매칭
@Column
private String name;
name
: 필드와 매칭할 테이블의 칼럼의 이름을 지정, default는 필드 이름으로 대체
insertable
: true -> 엔티티 저장 시 필드 값 저장, false -> 필드 값 저장 되지 않음
처음에 DDL 동작 시 사용된 쿼리를 보면 이해 쉬움
updatable
: true -> 엔티티 수정 시 값이 수정, false -> 엔티티 수정 시 값이 수정되지 않음
ex) 생성 날짜 필드
table
: 하나의 엔티티를 두개 이상의 테이블에 매핑할 때 사용
nullable
: null값 허용 여부
unique
: 컬럼에 유니크 제약 조건 부여
columnDefinition
: 데이터 베이스 컬럼 정보를 직접 부여
length
: 문자 길이 제약
precision
,scale
: BigDecimal 타입에서 자릿수 설정 시 주로 사용
insertable
//Entity
@Entity(name="user2")
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User {
@Id
@GeneratedValue
private Long id;
@Column(insertable = false)
private String name;
private String age;
}
//Service
@Service
@RequiredArgsConstructor
public class TestService {
private final EntityManager em;
@Transactional
public void test() {
User user = User.builder()
.age("12")
.name("test")
.build();
em.persist(user);
}
}
이때 네임 컬럼에 test를 입력하였더라도 DB에는 값이 들어가지 않음
updatable
@Entity(name="user2")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Setter
public class User {
@Id
@GeneratedValue
private Long id;
@Column(updatable = false)
private String name;
private String age;
}
//Service
@Service
@RequiredArgsConstructor
public class TestService {
private final EntityManager em;
@Transactional
public void test() {
User user = User.builder()
.age("12")
.name("test")
.build();
em.persist(user);
user.setName("change test");
}
}
이때도 마찬가지로 change test로 변경값이 지정되지 않음
columnDefinition
@Entity(name="user2")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Setter
public class User {
@Id
@GeneratedValue
private Long id;
@Column(unique = true)
private String name;
@Column(columnDefinition = "VARCHAR(15) NOT NULL")
private String age;
}
JPA가 엔티티 데이터에 접근하는 방식 지정
AccessType.FIELD
: 필드에 직접 접근, private이여도 가능
AccessType.PROPERTY
: getter를 통해 접근
@Access 어노테이션 지정 안할 시 @Id의 위치를 기준으로 접근
@Entity(name = "user2")
@Table(name = "user3")
@Getter
@Setter
@Access(AccessType.FIELD)
public class User {
@Id
@GeneratedValue
private Long id;
}
기본적으로 위 코드에 @Access(AccessType.FIELD)가 있을 때와 없을 때의 동작 방식이 같음
-> @Id 어노테이션 설정 시 기본적으로 적용
프로퍼티 접근 사용 예시
@Entity(name = "user2")
@Table(name = "user3")
@Setter
@Access(AccessType.PROPERTY)
public class User {
@GeneratedValue
private Long id;
@Id
public Long getId() {
return id;
}
}
프로퍼티 접근 + 필드 접근 혼용 예시
@Entity(name = "user2")
@Table(name = "user3")
@Getter
@Setter
public class User {
@Id
@GeneratedValue
private Long id;
@Transient
private String name;
@Access(AccessType.PROPERTY)
public String getFullName() {
return name + " hello";
}
protected void setFullName(String firstName) { }
}
//Service
@Service
@RequiredArgsConstructor
public class TestService {
private final EntityManager em;
@Transactional
public void test() {
User user = new User();
user.setName("aaa");
em.persist(user);
}
}
위 경우 칼럼명이 aaa hello로 지정됨
자바 enum 타입을 매핑할 때 사용
value
:
EnumType.ORDINAL : enum 순서를 DB에 저장
EnumType.STRING : enum 이름을 db에 저장
예시
//Enum 클래스
public enum RoleType {
ADMIN, USER
}
//Entity
@Entity(name = "user2")
@Table(name = "user3")
@Getter
@Setter
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
@Enumerated(value = EnumType.ORDINAL)
private RoleType ordinal;
@Enumerated(value = EnumType.STRING)
private RoleType string;
}
//Service
@Service
@RequiredArgsConstructor
public class TestService {
private final EntityManager em;
@Transactional
public void test() {
User user = new User();
user.setName("test");
user.setOrdinal(RoleType.ADMIN);
user.setString(RoleType.ADMIN);
em.persist(user);
}
}
String ADMIN으로 지정된 반면 ordinal은 ADMIN의 순서인 0이 지정되었음
만약 enum의 ADMIN앞에 값이 추가된다면 ADMIN은 순서 상 1번이 되므로 조회가 안됨
-> 되도록이면 STRING을 사용하자
날짜 타입을 매핑할때 주로 사용
value
:
TemporalType.DATE : 날짜, DB date 타입과 매핑(ex:2020-02-12)
TemporalType.TIME : 시간, Db time 타입과 매핑(ex: 12:12:12)
TemporalType.TIMESTAMP : 날짜와 시간 DB timestamp 타입과 매핑(2020-02-12 12:12:12)
Db BLOB, CLOB 타입과 매핑하기 위해 사용
정의할 속성은 따로 없지만 필드 타입이 문자열이면 CLOB, 나머지는 BLOB를 매핑
-> String, int가 있다면 각각 LONGTEXT, LONGBLOB로 매핑됨
이 어노테이션 붙인 필드는 DB에 저장 및 조회하지 않음
entity는 데이터의 대한 객체이기에 DB RECORD 그대로 반영하지만 객체로서 역할도 하기에 DB RECORD와는 별개로 필드를 가지고 싶어하는 니즈도 있음
-> 붙이면 영속성 처리에서 제외가 됨
붙인 칼럼은 DB칼럼에 추가되지 않는것 확인 가능