@Entity 어노테이션을 사용하면 JPA가 해당 클래스를 엔티티로 인식하여 관리하게 됩니다. 엔티티 클래스 작성 시 주의할 점과 @Entity 어노테이션의 속성에 대해 정리해 보겠습니다.
@Entity 어노테이션
@Entity 어노테이션은 JPA가 해당 클래스를 엔티티로 인식하고, 데이터베이스 테이블과 매핑할 수 있도록 합니다. 이 어노테이션은 클래스 수준에 적용해야 합니다.
주의 사항
- 기본 생성자:
- JPA가 엔티티 객체를 생성할 때 사용합니다.
- 반드시 파라미터가 없는 public 또는 protected 기본 생성자가 필요합니다.
- final 키워드 사용 제한:
- 엔티티의 필드에는 final 키워드를 사용할 수 없습니다. JPA가 엔티티의 상태를 변경할 수 있어야 하기 때문입니다.
- 필수 어노테이션:
- JPA를 사용하여 데이터베이스 테이블과 매핑하려면 해당 클래스에 @Entity 어노테이션을 반드시 붙여야 합니다.
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Member {
@Id
private Long id;
private String name;
}
@Table 어노테이션은 엔티티 클래스와 매핑할 테이블을 지정하는 데 사용됩니다. 이 어노테이션은 엔티티 클래스에 적용되며, 다양한 속성을 통해 테이블의 세부 매핑을 설정할 수 있습니다.
@Table 어노테이션 속성
- name: 매핑할 테이블의 이름을 지정합니다.
- 기본값: 엔티티 이름을 사용합니다.
- catalog: 데이터베이스의 카탈로그를 매핑합니다.
- 특정 데이터베이스의 카탈로그를 지정할 수 있습니다.
- schema: 데이터베이스의 스키마를 매핑합니다.
- 특정 데이터베이스의 스키마를 지정할 수 있습니다.
- uniqueConstraints: 테이블에 고유 제약 조건(Unique Constraints)을 설정합니다.
- @UniqueConstraint 어노테이션을 사용하여 제약 조건을 지정할 수 있습니다.
JPA에서 데이터베이스 스키마를 자동으로 생성하는 기능은 개발 단계에서 매우 유용합니다. 이를 통해 엔티티 클래스의 변경 사항을 데이터베이스 스키마에 자동으로 반영할 수 있습니다. 이 기능은 hibernate.hbm2ddl.auto 속성을 통해 설정할 수 있으며, 다양한 옵션을 제공합니다.
hibernate.hbm2ddl.auto 속성
이 속성은 애플리케이션 실행 시점에 데이터베이스 스키마를 어떻게 처리할지를 정의합니다. 각 옵션의 설명은 다음과 같습니다:
- create
- 설명: 기존 테이블을 삭제한 후 다시 생성합니다. DROP과 CREATE 명령을 사용하여 모든 테이블을 초기화합니다.
- 사용 시점: 개발 초기 단계나 테스트 환경에서 사용합니다.
- 주의 사항: 기존 데이터가 모두 삭제되므로 중요한 데이터가 있는 운영 환경에서는 사용하지 않습니다.
- create-drop
- 설명: create와 동일하지만, 애플리케이션 종료 시점에 테이블을 삭제합니다.
- 사용 시점: 단기 테스트나 임시 데이터베이스 환경에서 사용합니다.
- 주의 사항: 애플리케이션 종료 시 모든 데이터가 삭제되므로, 장기적인 테스트나 운영 환경에서는 사용하지 않습니다.
- update
- 설명: 변경된 부분만 반영합니다. 기존 테이블 구조를 유지하면서 필요한 경우 스키마를 업데이트합니다.
- 사용 시점: 개발 단계에서 엔티티 클래스의 변경 사항을 반영할 때 유용합니다.
- 주의 사항: 운영 환경에서는 사용하지 않는 것이 좋습니다. 스키마의 복잡한 변경이 예상치 못한 문제를 일으킬 수 있습니다.
- validate
- 설명: 엔티티 클래스와 데이터베이스 테이블이 정상적으로 매핑되었는지 확인합니다. 스키마 변경은 수행하지 않습니다.
- 사용 시점: 애플리케이션 실행 전에 매핑이 올바른지 검증할 때 사용합니다.
- 주의 사항: 매핑이 올바르지 않으면 예외가 발생합니다.
- none
- 설명: 스키마 자동 생성 기능을 사용하지 않습니다.
- 사용 시점: 스키마 자동 생성을 원하지 않는 경우 사용합니다.
- 주의 사항: 개발 단계에서 스키마 변경 사항을 수동으로 반영해야 합니다.
데이터베이스 스키마 자동 생성 - 주의
운영 장비에는 절대 create, create-drop, update 사용하면 안된다.
개발 초기 단계는 create 또는 update 스테이징과 운영 서버는 validate 또는 none
JPA의 DDL 생성 기능을 통해 엔티티 클래스를 정의할 때 제약 조건을 추가할 수 있습니다. 이러한 제약 조건은 데이터베이스 테이블을 생성할 때만 적용되며, 실제 JPA의 실행 로직에는 영향을 미치지 않습니다. 이는 개발 단계에서 유용하며, 데이터베이스 스키마를 자동으로 생성할 때 필요한 제약 조건을 쉽게 정의할 수 있습니다.
1. DDL (Data Definition Language)
DDL은 데이터베이스 구조를 정의하고 수정하는 데 사용됩니다. 주요 작업으로는 테이블이나 인덱스를 생성, 수정, 삭제하는 것이 포함됩니다. 예를 들어, 새로운 테이블을 만들거나 기존 테이블의 구조를 변경하는 작업이 있습니다.
2. DML (Data Manipulation Language)
DML은 데이터베이스의 데이터를 조작하는 데 사용됩니다. 주로 데이터를 삽입, 수정, 삭제, 조회하는 작업을 수행합니다. 애플리케이션에서 주로 사용되는 명령어 그룹으로, 데이터를 추가하거나 변경하는 작업을 담당합니다.
3. DCL (Data Control Language)
DCL은 데이터베이스 사용 권한을 제어하는 데 사용됩니다. 특정 사용자에게 데이터베이스 객체에 대한 접근 권한을 부여하거나 회수하는 작업을 수행합니다. 보안 측면에서 중요한 역할을 합니다.
4. TCL (Transaction Control Language)
TCL은 트랜잭션을 제어하는 데 사용됩니다. 하나의 작업 단위로 묶여 있는 SQL 문장 집합의 변경 사항을 저장하거나 취소하는 작업을 수행합니다. 이를 통해 데이터의 일관성과 무결성을 유지합니다. 트랜잭션을 커밋하여 변경 사항을 저장하거나 롤백하여 변경 사항을 취소할 수 있습니다.
필트와 컬럼 매핑
package org.example;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "user")
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;
// Getters and Setters
}
매핑 어노테이션 정리
JPA와 Hibernate를 사용할 때, 엔티티 클래스의 필드를 데이터베이스의 컬럼과 매핑하기 위해 다양한 어노테이션을 사용합니다. 주요 매핑 어노테이션과 그 역할은 다음과 같습니다:
@Column
설명: 엔티티의 필드를 데이터베이스의 컬럼과 매핑합니다.
- name: 매핑할 테이블의 컬럼 이름을 지정합니다.
- nullable: null 값 허용 여부를 설정합니다.
- length: 문자열 타입의 컬럼 길이를 지정합니다.
- unique: 유니크 제약 조건을 설정합니다.
@Column(name = "member_name", nullable = false, length = 50)
private String name;
@Temporal
설명: 날짜 타입(java.util.Date, java.util.Calendar)을 매핑할 때 사용합니다.
- TemporalType.DATE: 날짜만 저장 (yyyy-MM-dd)
- TemporalType.TIME: 시간만 저장 (HH:mm)
- TemporalType.TIMESTAMP: 날짜와 시간 모두 저장 (yyyy-MM-dd HH:mm)
@Temporal(TemporalType.TIMESTAMP)
private Date joinDate;
@Enumerated
설명: enum 타입을 매핑할 때 사용합니다.
- EnumType.ORDINAL: enum 순서를 데이터베이스에 저장
- EnumType.STRING: enum 이름을 데이터베이스에 저장
@Enumerated(EnumType.STRING)
private MemberType memberType;
@Lob
- 설명: BLOB(Binary Large Object)와 CLOB(Character Large Object) 타입을 매핑합니다. BLOB은 바이너리 데이터를, CLOB은 텍스트 데이터를 저장합니다.
@Lob
private byte[] profilePicture;
@Lob
private String description;
@Transient
- 설명: 특정 필드를 데이터베이스 컬럼에 매핑하지 않고 매핑을 무시합니다. 해당 필드는 데이터베이스에 저장되지 않습니다.
@Transient
private String tempData;
기본 키 매핑 방법
JPA에서 엔티티의 기본 키를 매핑하는 방법에는 여러 가지가 있습니다. 각 방법의 특징과 사용법을 정리하면 다음과 같습니다.
직접 할당
- 설명: 애플리케이션에서 기본 키 값을 직접 할당합니다.
- 어노테이션: @Id
@Entity
public class Member {
@Id
private Long id;
// 기타 필드와 메서드
}
자동 생성(@GeneratedValue)
JPA는 기본 키를 자동으로 생성하는 방법을 제공합니다. 이를 위해 @GeneratedValue 어노테이션을 사용하며, 다음과 같은 전략을 선택할 수 있습니다.
IDENTITY
- 설명: 기본 키 생성을 데이터베이스에 위임합니다. MySQL, PostgreSQL, SQL Server, DB2 등에서 사용됩니다.
- 특징:
- 데이터베이스에 INSERT SQL 실행 후, 기본 키 값을 알 수 있습니다.
- em.persist() 시점에 즉시 INSERT SQL을 실행하여 식별자를 조회합니다.
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// 기타 필드와 메서드
}
SEQUENCE
- 설명: 데이터베이스 시퀀스 오브젝트를 사용하여 기본 키를 생성합니다. 주로 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용됩니다.
- 특징:
- 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트입니다.
- @SequenceGenerator 어노테이션을 사용하여 시퀀스를 지정할 수 있습니다.
@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;
// 기타 필드와 메서드
}
TABLE
- 설명: 키 생성용 테이블을 사용하여 기본 키를 생성합니다. 모든 데이터베이스에서 사용할 수 있습니다.
- 특징:
- 키 생성 전용 테이블을 사용하여 시퀀스처럼 동작하게 합니다.
- @TableGenerator 어노테이션을 사용하여 키 생성 테이블을 지정할 수 있습니다.
@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;
// 기타 필드와 메서드
}
AUTO
- 설명: 기본 키 생성 전략을 방언에 따라 자동으로 선택합니다. 기본값으로 사용됩니다.
- 특징:
- 데이터베이스 방언에 맞는 적절한 기본 키 생성 전략을 자동으로 선택합니다.
@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;
// 기타 필드와 메서드
}
권장하는 식별자 전략
식별자 전략을 선택할 때는 기본 키의 특성과 조건을 고려하는 것이 중요합니다. 기본 키는 다음과 같은 조건을 만족해야 합니다:
- null이 아님
- 유일함
- 변하지 않음
미래까지 이 조건을 만족하는 자연 키를 찾기는 어렵기 때문에 대리 키(대체 키)를 사용하는 것이 좋습니다. 예를 들어, 주민등록번호와 같은 자연 키는 기본 키로 사용하기 적절하지 않습니다.
따라서, 권장하는 식별자 전략은 다음과 같습니다:
- Long형 + 대체 키 + 키 생성 전략 사용
권장되는 키 생성 전략
- 자동 생성(@GeneratedValue)
- IDENTITY: MySQL, PostgreSQL, SQL Server, DB2 등에서 사용
- SEQUENCE: Oracle, PostgreSQL, DB2, H2 등에서 사용
- TABLE: 모든 DB에서 사용 가능
- AUTO: 방언에 따라 자동 지정, 기본값
'JPA' 카테고리의 다른 글
[JPA] JPA 연관관계 매핑 (2) (0) | 2024.06.29 |
---|---|
[JPA] JPA 연관관계 매핑 (1) (0) | 2024.06.29 |
[JPA] JPA 영속성 관리 (0) | 2024.06.29 |
[JPA] JPA 생성 및 개발 (0) | 2024.06.29 |
[JPA] JPA 소개 (0) | 2024.06.29 |