자바 ORM 표준 JPA 프로그래밍(기본편) - 엔티티 매핑

최준석·2022년 10월 26일
0

엔티티 매핑


목차

  • 객체와 테이블 매핑
  • 데이터베이스 스키마 자동 생성
  • 필드와 컬럼 매핑
  • 기본 키 매핑

1. 객체와 테이블 매핑

@Entity

  • @Entity가 붙은 클래스는 JPA가 관리하며, 엔티티라고 부른다
  • JPA를 사용해 테이블과 매핑할 클래스는 @Entity 필수
  • 주의
    • 기본생성자 필수(파라미터가 없는 public 또는 protected 생성자)
    • final 클래스, enum, interface, inner 클래스 들은 사용할 수 없다
    • 저장할 필드에 final 을 사용할 수 없다

@Entity의 속성

  • @Entity(name = "")
    • JPA에서 사용할 엔티티 이름
    • 정해주지 않으면 클래스 이름을 그대로 사용한다
    • 동일한 클래스명으로 중복이 일어나지 않으면 가급적 그대로 사용하자

@Table의 속성

  • @Table어노테이션을 사용해 엔티티와 매핑할 테이블을 지정할 수 있다.
  • @Table(name = "")
    • 매핑할 테이블 이름(설정없으면 엔티티 이름 사용)
  • @Table(catalog = "")
    • 데이터베이스 catalog를 매핑할 때 사용
  • @Table(schema = "")
    • 데이터베이스 schema를 매핑할 때 사용
  • @Table(uniqueConstraints = "")
    • DDL 생성시에 유니크 제약 조건 생성


2. 데이터베이스 스키마 자동 생성

  • DDL(Data Definition Language)을 애플리케이션 실행 시점에 자동으로 생성해준다
  • 테이블 중심이 아니라 객체 중심으로 개발이 가능해진다
  • 데이터베이스 방언을 활용해서 데이터베이스에 맞는 DDL을 생성해준다
  • 하지만, 이렇게 생성된 DDL은 개발 장비에서만 사용하는게 좋다
    (자동으로 생성되는 DDL은 자칫 운영서버에 큰 피해를 줄 수 있다)

hibernate.hbm2ddl.auto 의 속성

  • create : 기존 테이블을 삭제 후 다시 생성(DROP + CREATE)
  • create-drop : create와 같으나 종료시점에 테이블 DROP
  • update : 변경분만 반영(그래도 운영DB에는 사용하면 안됨)
  • validate : 엔티티와 테이블이 정상 매핑되었는지만 확인
  • none : 사용하지 않음
  • 주의
    • 운영장비에는 create, create-drop, update 를 사용하면 안된다
      • 개발 초기 단계는 create 또는 update
      • 테스트 서버는 update 또는 validate
      • 스테이징과 운영 서버는 validate 또는 none

DDL 생성 기능

  • 제약조건 추가 : @Column(nullable = false, length = 10)
  • 유니크 제약조건 추가 : @Table(uniqueConstraints = {@UniqueConstraint( name = "NAME_AGE_UNIQUE", columnNames = {"NAME", "AGE"} )})
  • DDL 생성 기능은 DDL을 자동 생성할 때만 사용되고
    JPA의 실행 로직에는 영향을 주지 않는다

3. 필드와 컬럼 매핑

예시)

package hellojpa;
import javax.persistence.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;

@Entity
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;
//Getter, Setter…
}

매핑 어노테이션

hibernate.hbm2ddl.auto

  • @Column : 컬럼 매핑
  • @Temporal : 날짜 타입 매핑
  • @Enumerated : enum 타입 매핑
  • @Lob : BLOB, CLOB 매핑
  • @Transient : 특정 필드를 컬럼에 매핑하지 않음(매핑 무시)

@Column의 속성

  • @Column(name = "") : 필드와 매핑할 테이블의 컬럼 이름(기본값 : 객체의 필드이름)
  • @Column(insertable = "", updatable = "") : 등록, 변경 가능 여부(기본값 : TRUE)
  • @Column(nullable = "") : notNull 제약조건 사용여부
  • @Column(unique = "") : unique 제약조건 사용여부
  • @Column(columnDefinition = "") : 컬럼정보를 직접 입력할 수 있다(기본값 : 필드의 자바타입과 방언 정보를 사용해 생성)
  • @Column(length = "") : 문자 길이 제약조건, String 타입에만 사용(기본값 : 255)
  • @Column(precision = "", scale = "") : BigDecimal 타입에서 사용한다(BigInteger도 사용할 수 있다).
    precision은 소수점을 포함한 전체 자릿수를, scale은 소수의 자릿수다. 참고로 double, float 타입에는 적용되지 않는다. 아주 큰 숫자나정 밀한 소수를 다루어야 할 때만 사용한다.

@Enumerated의 속성

자바 enum 타입을 매핑할 때 사용

  • @Enumerated(value = "")(기본값 : EnumType.ORDINAL)
    • EnumType.ORDINAL : enum 순서를 데이터베이스에 저장하는 방식
    • EnumType.STRING : enum 이름을 데이터베이스에 저장
  • 주의 : ORDINAL은 사용하지 말자!(Enum 내부 데이터 추가시 기존 순서에 끼워넣는 식으로 추가 했을 때 Index가 밀려버림)

@Temporal의 속성

날짜 타입(java.util.Date, java.util.Calendar)을 매핑할 때 사용
참고 : LocalDate, LocalDateTime을 사용할 때는 생략 가능(JAVA 8버전 부터 지원)

  • @Temporal(value = "")
    • TemporalType.DATE: 날짜, 데이터베이스 date 타입과 매핑(예: 2013–10–11)
    • TemporalType.TIME : 시간, 데이터베이스 time 타입과 매핑(예: 11:11:11)
    • TemporalType.TIMESTAMP : 날짜와 시간, 데이터베이스 timestamp 타입과 매핑(예: 2013–10–11 11:11:11)

@Lob

데이터베이스 BLOB, CLOB 타입과 매핑

  • @Lob에는 속성이 없다
  • 매핑하는 필드 타입이 문자면 CLOB 매핑, 나머지는 BLOB 매핑
    • CLOB: String, char[], java.sql.CLOB
    • BLOB: byte[], java.sql. BLOB

@Transient

  • 필드가 데이터베이스의 컬럼과 매핑되지 않는다
  • 데이터베이스에 관련없이 작동한다
  • 주로 메모리상에서만 임시로 어떤값을 보관하고 싶을 때 사용

4. 기본 키 매핑

기본 키 매핑 어노테이션

@Id
@GeneratedValue

예시)

@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

기본 키 매핑 방법

직접 할당 : @Id만 사용
자동 생성 : @GeneratedValue

  • GenerationType.IDENTITY : 데이터베이스에 위임, MYSQL
  • GenerationType.SEQUENCE : 데이터베이스 시퀀스 오브젝트 사용, ORACLE
    • @SequenceGenerator 필요
  • GenerationType.TABLE : 키 생성용 테이블 사용, 모든 DB에서 사용
    • @TableGenerator 필요
  • GenerationType.AUTO : 방언에 따라 자동 지정, 기본값

IDENTITY전략 특징

  • 기본 키 생성을 데이터베이스에 위임
  • 주로 MySQL, PostgreSQL, SQL Server, DB2 에서 사용
    (예 : MySQL의 AUTO_INCREMENT)
  • JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL 실행하지만 키 생성을 DB에 위임하면 INSERT SQL 후에 ID를 알 수 있으므로 IDENTITY 전략은 em.persist()시점에 바로 INSERT 쿼리문을 실행하고 식별자를 조회한다.

SEQUENCE전략 특징

  • 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트(예 : 오라클 시퀀스)
  • 오라클, PostgreSQL, DB2, H2데이터베이스에서 사용

예시)

@Entity
@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;

@SequenceGenerator의 속성

주의 : allocationSize 기본값 = 50

  • @SequenceGenerator(name = "") : 식별자 생성기 이름(기본값 : 필수)
  • @SequenceGenerator(sequenceName = "") : 데이터베이스에 등록되어 있는 시퀀스 이름(기본값 : hibernate_sequence)
  • @SequenceGenerator(initialValue = "") : DDL 생성 시에만 사용됨, 시퀀스 DDL을 생성할 때 처음 1 시작하는 수를 지정한다.(기본값 : 1)
  • @SequenceGenerator(allocationSize = "") : 시퀀스 한 번 호출에 증가하는 수(성능 최적화에 사용됨 데이터베이스 시퀀스 값이 하나씩 증가하도록 설정되어 있으면 이 값을 반드시 1로 설정해야 한다(기본값 : 50)
  • @SequenceGenerator(catalog = "", schema = "") : 데이터베이스 catalog, schema 이름

TABLE전략 특징

  • 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략
  • 장점 : 모든 데이터베이스에 적용 가능
  • 단점 : 성능

예시)

@Entity
@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;

@TableGenerator의 속성

  • @TableGenerator(name = ""): 식별자 생성기 이름(기본값 : 필수)
  • @TableGenerator(table = ""): 키 생성 테이블명(기본값 : hibernate_sequences)
  • @TableGenerator(pkColumnName = ""): 시퀀스 컬럼명(기본값 : sequence_name)
  • @TableGenerator(valueColumnName = ""): 시퀀스 값 컬럼명(기본값 : next_val)
  • @TableGenerator(pkColumnValue = ""): 키로 사용할 값 이름(기본값 : 엔티티 이름)
  • @TableGenerator(initialValue = ""): 초기 값, 마지막으로 생성된 값이 기준이다(기본값 : 0)
  • @TableGenerator(allocationSize = ""): 시퀀스 한 번 호출에 증가하는 수(성능 최적화에 사용됨, 기본값 : 50)
  • @TableGenerator(catalog = "", schema = ""): 데이터베이스 catalog, schema 이름
  • @TableGenerator(uniqueConstraint s = ""): 유니크 제약 조건을 지정할 수 있다

권장하는 식별자 전략

  • 기본 키 제약 조건 : NotNull, 유일, 변하면 안된다
  • 미래까지 이 조건을 만족하는 자연키는 찾기 어렵다. 대리키(대체키)를 사용하자
  • 예를들어 주민번호도 기본키로 적절하지 않다
  • 권장 : Long형 + 대체키 + 키 생성전략 사용

출처 : https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
(자바 ORM 표준 JPA 프로그래밍 - 기본편)

profile
Back-End Web Developer

0개의 댓글