[Spring]자바 ORM 표준 JPA 프로그래밍 - 엔티티 매핑
📝엔티티 매핑
JPA의 엔티티를 관리하기 위한 매핑에 대해 알아보자
엔티티 매핑은 4가지가 존재한다.
매핑 | 애노테이션 |
객체 매핑 | @Entity |
테이블 매핑 | @Table |
컬럼 매핑 | @Column |
필드 매핑 | @Temporal,@Enumerated, @Lob, @Transient |
기본키 매핑 | @Id |
연관관계 매핑 | @ManyToOne, @JoinColumn |
객체 매핑 - @Entity
@Entity가 붙은 클래스는 JPA가 관리하는 엔티티가 된다.
속성
- @Entity(name = "") : JPA에서 사용할 엔티티 이름을 지정할 수 있다.
테이블 매핑 - @Table
@Table은 엔티티와 매핑할 테이블을 지정할 수 있다.
속성
- name : 매핑할 테이블 이름
- catalog : 데이터베이스 catalog 매핑
- schema : 데이터베이스 schema 매핑
- uniqueConstraints : DDL 생성 시에 유니크 제약 조건 생성
컬럼 매핑 - @Column
@Column은 컬럼에 대한 매핑과 제약조건을 추가할 수 있다.
속성
- name : 필드와 매핑할 테이블의 컬럼 이름
- insertable, updatable : 등록, 변경 가능 여부
- nullable : null 값 허용 여부
- unique : 유니크 제약조건
- columnDefinition : 데이터 컬럼 정보를 직접 줄 수 있다.
- length : 문자 길이 제약 조건, String 타입만 사용
필드 매핑
각 형태에 따라 매핑하는 기능을 지원한다.
애노테이션 | 설명 |
@Column | 컬럼 매핑 |
@Temporal | 날짜 타입 매핑 |
@Enumerated | enum 타입 매핑 |
@Lob | BLOB, CLOB 매핑 |
@Transient | 특정 필드를 컬럼에 매핑하지 않음(매핑 무시) |
@Entity
@Getter
@Setter
public class Member {
@Id
private Long id;
@Column(name = "name")
private String username;
private Integer age;
@Enumerated(EnumType.STRING)
private RoleType roleType;
@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;
@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
@Lob
private String description;
}
@Enumerated
자바 enum 타입 매핑에 사용
속성
- value
- EnumType.ORDINAL : enum 순서를 데이터베이스에 저장
- EnumType.STRING : enum 이름을 데이터베이스에 저장
주의! ORDINAL 사용하지 말것 ORDINAL은 순서 숫자를 저장하기 때문에 가독성과 유지보수성이 떨어진다.
@Temporal
날짜 타입을 매핑할 때 사용한다
그러나 최신 하이버네이트판에서는 LocalDate, LocalDateTime을 사용하기 때문에 생략이 가능하다.
@Lob
Lob은 지정할 수 있는 필드가 없다.
매핑하는 필드 타입이 문자면 CLOB 이고, 나머지는 BLOB를 매핑한다.
@Transient
필드 매핑을 X 제외한다.
데이터베이스에 저장, 조회를 막으며 주로 메모리 상에서만 임시로 어떤 값을 보관하고 싶을 때 사용한다.
🚩데이터베이스 스키마 자동 생성
DDL은 매핑 정보를 이용해 애플리케이션 실행 시점에 데이터베이스 스키마를 자동으로 생성해준다.
이렇게 생성된 데이터베이스는 개발 장비로만 사용하는 것이 좋다.
또한 자동 생성에 대한 속성을 지정할 수 있다.
//application.yml
jpa:
hibernate:
ddl-auto: create
옵션 | 설명 |
create | 기존 테이블 삭제 후 다시 생성 |
create-drop | create와 같으나 종료시점에 테이블을 DROP |
update | 변경분만 반영 |
validate | 엔티티와 테이블이 정상 매핑되었는지만 확인 |
none | 사용하지 않음 |
주의사항!
운영 장비에는 절대 create, create-drop, update를 절대 사용하면 안된다.
- 개발 초기 단계는 create 또는 update
- 테스트 서버는 update 또는 validate
- 스테이징과 운영서버는 validate 또는 none을 사용해야 한다.
📝기본 키 매핑
JPA는 엔티티를 매핑한 이후에도 기본 키는 개발자가 직접 지정해줘야 한다.
간단하게 @Id를 사용하면 되지만
다양한 속성을 지정할 수 있다.
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id
JPA의 자동생성 전략 @GeneratedValue은 엔티티의 기본키를 생성하는 전략을 지정해 준다.
속성 | 전략 |
IDENTITY | 데이터베이스에 위임, MYSQL |
SEQUENCE | 데이터베이스 시퀀스 오브젝트 사용, 오라클 |
TABLE | 키 생성용 테이블 사용, 모든 DB에 적용 |
AUTO | 방언에 따라 자동지정 |
IDENTITY 전략
기본 키 생성을 전적으로 데이터베이스에 위임한다.
MYSQL의 auto-increment을 사용하는 전략이다.
즉, 저장 시점에서 auto-increment를 이용해 자동으로 기본 키를 할당하며 기본키는 여태까지의 INSERT연산 횟수 + 1이다.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
SEQUENCE 전략
데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트이다.
오라클,H2 등의 데이터베이스에서 사용한다.
시퀀스 전략은 @SequenceGenerator 애노테이션을 따로 지정해 줘야 한다.
@Entity
@Data
@SequenceGenerator(name = "MEMBER_SEQ_GENERATOR", sequenceName = "MEMBER_SEQ", initialValue = 1, allocationSize = 1)
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "MEMBER_SEQ_GENERATOR")
private Long id;
@Column(name = "name")
private String name;
}
TABLE 전략
키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략
장점은 모든 데이터베이스에 적용 가능하나 단점을 성능이 별로다.
@Entity
@Data
@TableGenerator(
name = "MEMBER_SEQ_GENERATOR", table = "MY_SEQUENCES", pkColumnValue = "MEMBER_SEQ", allocationSize = 1)
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR")
private Long id;
@Column(name = "name")
private String name;
}