엔티티 설계
Spring Data JPA를 사용하면 데이터베이스에 테이블을 생성하기 위해 직접 쿼리를 작성할 필요가 없습니다. 이 기능을 가능하게 하는 것이 엔티티입니다. JPA에서 엔티티는 데이버테이스의 테이블에 대응하는 클래스입니다. 엔티티는 데이터베이스에 쓰일 테이블과 칼럼을 정의합니다. 엔티티에 어노테이션을 사용하면 테이블 간의 연관관계를 정의할 수 있습니다.
package com.springboot.jpa.data.entity;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long number;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private Integer price;
@Column(nullable = false)
private Integer stock;
private LocalDateTime createdAt;
private LocalDateTime updateAt;
... getter/setter 메서드 생략 ...
}
위와 같이 클래스를 생성하고 spring.jpa.hibernate.ddl-auto의 값을 create 같은 테이블을 생성하는 옵션으로 설정하면 쿼리문을 작성하지 않아도 데이터베이스에 테이블이 자동으로 만들어집니다.
엔티티 관련 기본 어노테이션
엔티티를 작성할 때는 어노테이션을 많이 사용합니다. 그중에는 테이블과 매핑하기 위해 사용하는 어노테이션도 있고, 다른 테이블과의 연관관계를 정의하기 위해 사용하는 어노테이션, 자동으로 값을 주입하기 위한 어노테이션도 있습니다.
@Entity
해당 클래스가 엔티티임을 명시하기 위한 어노테이션입니다. 클래스 자체는 테이블과 일대일로 매칭되며, 해당 클래스의 인스턴스는 매핑되는 테이블에서 하나의 레코드를 의미합니다.
@Table
엔티티 클래스는 테이블과 매핑되므로 특별한 경우가 아니면 @Table 어노테이션이 필요하지 않습니다. @Table 어노테이션을 사용할 때는 클래스의 이름과 테이블의 이름이 다르게 지정해야 하는 경우입니다. @Table어노테이션을 명시하지 않으면 테이블의 이름과 클래스의 이름이 동일하다는 의미이며, 서로 다른 이름을 쓰려면 @Table(name = 값) 형태로 데이터베이스의 테이블명을 명시해야 합니다. 대체로 자바의 명명법과 데이터베이스가 사용하는 명명법이 다르기 때문에 자주 사용됩니다.
@Id
엔티티 클래스의 필드는 테이블의 칼럼과 매핑됩니다. @Id 어노테이션이 선언된 필드는 테이블의 기본키 역할로 사용됩니다. 모든 엔티티는 @Id 어노테이션이 필요합니다.
@GeneratedValue
일반적으로 @Id 어노테이션과 함께 사용됩니다. 이 어노테이션은 해당 필드의 값을 어떤 방식으로 자동으로 생성할지 결정할 때 사용합니다. 쉽게 말해 기본 키를 자동으로 생성해주는 어노테이션입니다. 속성으로 strategy 가 있으면 이를 통해 자동 생성 전략을 지정해줄 수 있습니다.
@GeneratedValue(strategy = GenerationType.IDENTITY
IDENTITY
- IDENTITY 전략은 기본 키 생성을 데이터베이스에 위임하는 전략입니다.
- 주로 MySQL, PostgreSQL, SQL Server에서 사용합니다.
- 데이터베이스의 AUTO_INCREMENT 기능을 통해 데이터베이스가 기본 키를 자동으로 생성해줍니다. IDENTITY 전략은 AUTO_INCREMENT 처럼 데이터베이스에 값을 저장하고 나서 기본 키 값을 구할 수 있을 때 사용합니다.
- 주의할점은 엔티티가 영속 상태가 되기 위해선 식별자가 꼭 필요합니다. IDENTITY 전략을 사용하면 식별자를 데이터베이스에서 지정하기 전까지 알 수 없기에 em.persist()를 하는 즉시 INSERT SQL이 데이터베이스에 전달됩니다.
- 즉, 이 전략은 트랜잭션을 지원하는 쓰기 지연이 동작하지 않습니다.
AUTO
- @GeneratedValue의 기본 설정값
- 기본값을 사용하는 데이터베이스에 맞게 자동 생성합니다.
SEQUENCE
- @SequenceGenerator 어노테이션으로 식별자 생성기를 설정하고 이를 통해 값을 자동 주입받습니다.
- SequenceGenerator를 정의할 때는 name, sequenceName, allocationSize를 활용합니다.
- @GeneratedValue에 생성기를 설정합니다.
TABLE
- 어떤 DBMS를 사용하더라도 동일하게 동작하기를 원할 경우 사용합니다.
- 식별자로 사용할 숫자의 보관 테이블을 별도로 생성해서 엔티티를 생성할 때마다 값을 갱신하며 사용합니다.
- @TableGenerator 어노테이션으로 테이블 정보를 설정합니다.
@Column
엔티티 클래스의 필드는 자동으로 테이블 칼럼으로 매핑됩니다. 그래서 별다른 설정을 하지 않을 예정이라면 이 어노테이션을 명시하지 않아도 괜찮습니다. @Column 어노테이션은 아래와 같이 필드에 몇가지 설정을 더할 때 사용합니다.
public @interface Column {
String name() default "";
boolean unique() default false;
boolean nullable() default true;
boolean insertable() default true;
boolean updatable() default true;
String columnDefinition() default "";
String table() default "";
int length() default 255;
int precision() default 0;
int scale() default 0;
}
@Column 어노테이션에서 많이 사용하는 요소는 다음과 같습니다.
- name : 데이터베이스의 칼럼명을 설정하는 속성입니다. 명시하지 않으면 필드명으로 지정됩니다.
- nullable: 레코드를 생성할 때 칼럼 값에 null 처리가 가능한지를 명시하는 속성입니다.
- length : 데이터베이스에 저장하는 데이터의 최대 길이를 설정합니다.
- unique : 해당 컬럼을 유니크로 설정합니다.
예시
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "product_name", nullable = false, length = 100)
private String name;
@Column(precision = 12, scale = 2, nullable = false)
private BigDecimal price;
@Column(columnDefinition = "TEXT", nullable = true)
private String description;
@Column(insertable = false, updatable = false)
private LocalDateTime createdAt;
// Getter, Setter
}
@Transient
엔티티에서 해당 필드가 데이터베이스에 매핑되지 않도록 설정할 때 사용됩니다. 데이터베이스 테이블에 저장하거나 조회할 필요가 없는 값을 엔티티에 추가하고자 할때 활용됩니다.
예시
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String firstName;
@Column(nullable = false)
private String lastName;
// 데이터베이스에 매핑되지 않음
@Transient
private String fullName;
// Getter, Setter
public String getFullName() {
return firstName + " " + lastName; // 런타임에 계산된 값
}
}
'웹 개발 > 🍃 SpringBoot' 카테고리의 다른 글
JPA | 리포지토리 인터페이스 설계 (0) | 2025.01.12 |
---|---|
@GeneratedValue(strategy = GenerationType.IDENTITY) 전략 제대로 이해하기 (0) | 2025.01.10 |
Hibernate hibernate.ddl-auto 속성 완벽 가이드 (0) | 2025.01.09 |
JPA | 영속성 컨텍스트 (0) | 2025.01.07 |
JPA | 하이버네이트 (0) | 2025.01.07 |