[JPA] Entity 만들기
목차
✨ JPA로 Entity 클래스 작성 시 사용되는 주요 어노테이션
- 객체와 테이블 매핑
`@Entity`, `@Table` - 기본 키 매핑
`@Id`, `@GeneratedValue(strategy = GenerationType.IDENTITY)` - 필드와 컬럼 매핑
`@Column`, `@Lob`, `@Enumerated(EnumType.STRING)`, `@Temporal(TemporalType.DATE)` - 연관 관계 매핑
`OneToOne`, `@ManyToOne`, `@OneToMany`, `@JoinColumn`, `@JoinTable` - 기타
`@Transient`, `@Embeddable`, `@Embedded`, `@MappedSuperclass`, `@Access( AccessType.FIELD | AccessType.PROPERTY)`
객체와 테이블 매핑
import jakarta.persistence.*;
@Entity
@Table(name = "users") // 생략 가능. 지정 시 테이블명 명확히 설정
public class User {
@Id
private Long id;
private String name;
}
@Entity란?
해당 클래스가 데이터베이스의 테이블과 매핑되는 JPA Entity 클래스임을 나타냅니다.
- 속성
1. name : JPA Entity 이름을 지정합니다.
(생략시, 클래스 이름을 Entity명으로 사용. JPQL 쿼리에서 이 이름으로 참조합니다.)
❗`@Entity` 사용 시, 중요한 점
- 기본 생성자가 필수 입니다.
(생성자를 직접 생성하면, 기본 생성자가 자동으로 생기지 않기 때문에 주의해야합니다.) - `final`,`enum`,`interface`,`inner` 클래스에는 사용할 수 없습니다.
- 필드에 final 키워드를 사용할 수 없습니다.
@Table이란?
매핑할 테이블의 이름이나 기타 속성을 지정할 수 있습니다.
- 속성
1. name : 매핑할 테이블의 이름을 정하는 속성
(생략 시, 클래스 이름을 테이블명으로 사용)
- 제약 조건
1. `uniqueConstraints` : 유니크, 이름을 직접 설정할 수 있습니다.
@Table(uniqueConstraints = {@UniqueConstraints
(
name = "name_unique",
columnNames= {"name"}
)
}
)
// 클래스
- DDL을 자동으로 생성할 때만 사용되며 Application 로직에는 영향이 없습니다.
기본 키 매핑
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
@Id란?
Entity의 기본 키(PK)를 지정할 때 사용합니다. (영속성 컨텍스트를 위해, `Long` Type이 가장 권장)
@GeneratedValue란?
Entity의 기본 키(PK)를 자동으로 생성할 때 사용합니다.
- `strategy` : 기본 키를 생성하는 방식을 지정합니다.
1. `AUTO` : JPA가 사용하는 DB에 따라 자동으로 선택
2. `IDENTITY` : DB의 auto_increment 기능을 사용하여 ID를 생성
3. `SEQUENCE` : DB 시퀀스 객체 사용하여 ID를 생성, `@SequenceGenerator`와 함께 사용
4. `TABLE` : 별도 테이블 생성하여 기본 키를 관리, `@TableGenerator`와 함께 사용 (성능 이슈, 권장 ❌)
IDENTITY 깨알 정보
기본적으로 AUTO_INCREMENT는 DB에 INSERT SQL이 실행된 이후 PK를 알 수 있지만 IDENTITY 전략은 트랜잭션 Commit 후가 아닌 `em.persist()` 시점에 즉시 INSERT SQL을 실행하여 PK를 바로 조회할 수 있다.
수동 생성 방법
Tutor tutor = new Tutor(1L, "minsu");
- 객체 생성 시, 생성자를 통해 파라미터를 수동으로 전달합니다.
❗JPA Entity를 생성할 때 기본 키는 필수로 생성해야 합니다
필드와 컬럼 매핑
@Entity
public class Customer {
@Id
@GeneratedValue
private Long id;
@Column(name = "full_name", nullable = false, length = 100)
private String name;
}
@Column이란?
해당 필드를 테이블의 컬럼과 매핑하며, 컬럼의 이름, 길이, null 여부 등 제약 조건을 설정할 수 있습니다.
- 속성
1. name : 객체 필드와 매핑할 테이블의 컬럼 이름 (기본값 : 객체 필드 이름)
2. columnDefinition : DDL 생성 시 데이터베이스 컬럼 정보를 직접 설정
3. insertable : 설정된 컬럼의 INSERT 가능 여부 (기본값 : true)
4. updatable : 설정된 컬럼의 UPDATE 가능 여부 (기본값 : true)
5. table : 다른 테이블에 매핑할 경우 지
- 제약 조건
1. nullable : DDL 생성 시 null 값의 허용 여부 설정 (기본값 : true)
2. unique : DDL 생성 시 하나의 컬럼에 유니크 제약조건을 설정
3. length : DDL 생성 시 문자 길이 제약조건 설정. 단, String만 사용가능 (기본값 : 255)
4. precision : 숫자형(예: `DECIMAL) 전체 자릿수 제한
5. scale : 숫자형의 소수점 이하 자릿수 제한
❗DDL을 자동으로 생성할 때만 사용되며 Application 로직에는 영향이 없습니다.
연관 관계 매핑
@Entity
public class Order {
@Id
@GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "user_id") // 외래 키 설정
private User user;
}
@ManyToOne이란?
다대일(N:1) 관계를 설정할 때 사용합니다.
@JoinColumn이란?
외래 키(FK) 컬럼을 지정하여 어떤 컬럼을 통해 연관 관계가 설정되는지 명시합니다.
❗의존성 추가
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
}
❗application.yml 설정
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<persistence-unit name="test"> <!-- createEntityManagerFactory에서 사용할 이름 -->
<class>org.entity.Tutor</class>
<properties>
<property name="jakarta.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<!-- DB 아이디 -->
<property name="jakarta.persistence.jdbc.user" value="root"/>
<!-- DB 비밀번호 -->
<property name="jakarta.persistence.jdbc.password" value="1111"/>
<!-- 스키마 -->
<property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/스키마 이름"/>
<!-- 스키마 자동생성 속성 -->
<property name="hibernate.hbm2ddl.auto" value="create" />
<!-- Hibernate가 DB에 전송하는 DDL, DML SQL을 콘솔에 출력한다. -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>
<!-- 한꺼번에 전송될 SQL 수량 설정 -->
<!-- <property name="hibernate.jdbc.batch_size" value="10"/> -->
</properties>
</persistence-unit>
</persistence>
hibernate.hbm2ddl.auto
JPA는 Application 로딩 시점에 DDL을 자동으로 생성하는 기능을 지원합니다. 방언(dialect)을 사용하여 Entity Mapping만 하여도 데이터베이스에 맞는 적절한 DDL이 생성됩니다.
❗자동으로 생성된 DDL은 실제 운영환경이 아닌 개발 환경에서만 사용합니다. 필요한 경우에는 자동으로 생성된 DDL을 직접 수정 후 적용합니다.
DDL 자동 생성 속성
값 | 설명 |
`create` | 기존 테이블을 삭제(DROP) 후 다시 생성(CREATE)합니다. |
`create-drop` | DROP 후 CREATE 하고 종료시점에 테이블을 삭제(DROP)합니다. 테스트 시 사용 |
`update` | 변경된 사항만 DDL에 반영합니다. |
`validate` | Entity와 테이블이 정상적으로 매핑 되었는지 확인합니다. 실패 시 예외 발생 |
`none` | 속성을 사용하지 않습니다. |
실제 운영환경에서 가장 많이 사용되는 것 : `validate` 또는 `none`
속성 값 | 설명 | 실무에서 선호되는 이유 |
`validate` | 매핑된 엔티티 구조가 DB 테이블과 일치하는지 검사합니다. 수정은 하지 않습니다. | DB를 보호하면서도 구조 일치 여부를 확인할 수 있어서 안전합니다. 배포 전 검증용으로 적합합니다. |
`none` | Hibernate가 DDL 관련 작업을 하지 않습니다. | DB 스키마 변경을 완전히 통제하고 싶을 때 사용합니다. DBA가 직접 스키마를 관리하는 환경에서 자주 사용합니다. |
- 개발 환경일 때는 상황에 맞게 사용하고 보통 `update`를 많이 사용합니다.
DDL 자동 생성 속성 설정 방법
hibernate.hbm2ddl.auto=create
- `application.properties`
<property name="hibernate.hbm2ddl.auto" value="create" />
- `application.yml`