- [JPA] 3. 매핑 종류(공사중..🚧)2025년 01월 11일 23시 26분 41초에 업로드 된 글입니다.작성자: nickhealthy
JPA에서 엔티티 매핑(Entity Mapping)은 객체 지향 프로그래밍에서 객체와 데이터베이스의 테이블 간의 관계를 정의하는 중요한 개념이다. JPA는 자바 객체와 관계형 데이터베이스의 테이블 간의 매핑을 통해 객체-관계 매핑(ORM)을 구현한다.
객체와 테이블 매핑
다음과 같은 개념이 존재한다. 차례대로 자세히 알아보자.
- 객체와 테이블 매핑: `@Entity`, `@Table`
- 필드와 컬럼 매핑: `@Column`
- 기본 키 매핑: `@Id`
- 연관관계 매핑: `@OneToOne`, `@OneToMany / @ManyToOne` , `@ManyToMany`, `@JoinColumn`
@Entity
- `@Entity` 붙은 클래스는 JPA가 관리, 해당 클래스가 엔티티임을 명시한다.
- 엔티티는 데이터베이스의 테이블과 매핑되는 자바 클래스를 의미하며, 필수 어노테이션이다.
[주의사항]
- 기본 생성자 필수(파라미터가 없는 `public` 또는 `protected` 생성자)
- JPA는 내부적으로 리플렉션을 사용하기 때문에 기본 생성자가 필요하다.
- final 클래스, enum, interface, inner 클래스 사용 X
- 저장할 필드에 final 사용 X
@Entity public class Employee { @Id private Long id; private String name; private String department; // Getters and Setters }
@Table
- JPA에서 엔티티 클래스와 데이터베이스 테이블 간의 매핑 정보를 제공하는 어노테이션이다.
- 기본적으로, JPA는 엔티티 클래스의 이름을 테이블 이름으로 사용하지만, `@Table`을 사용하여 매핑할 테이블 이름이나 기타 속성(스키마, 고유 제약 조건 등)을 명시적으로 설정할 수 있다.
@Table 어노테이션의 주요 속성
- name:
- 이 속성은 엔티티 클래스와 매핑할 데이터베이스 테이블의 이름을 지정한다. 기본적으로 클래스 이름과 같은 테이블을 사용하지만, @Table(name = "테이블_이름")을 사용하여 다른 테이블 이름을 지정할 수 있다.
위 예시에서 Employee 엔티티는 데이터베이스에서 employee_table이라는 이름의 테이블에 매핑된다.@Entity @Table(name = "employee_table") public class Employee { @Id private Long id; private String name; private String department; // Getters and Setters }
- schema:
- 이 속성은 테이블이 속할 스키마를 지정한다. 데이터베이스에서 여러 스키마를 사용하는 경우, 이 속성을 통해 특정 스키마에 테이블을 매핑할 수 있다.
위 예시에서는 employee_table이 hr라는 스키마에 매핑된다.@Entity @Table(name = "employee_table", schema = "hr") public class Employee { @Id private Long id; private String name; private String department; // Getters and Setters }
- catalog:
- 이 속성은 테이블이 속할 카탈로그를 지정한다. 카탈로그는 데이터베이스의 논리적인 그룹을 나타내며, 주로 DBMS에서 여러 데이터베이스를 구분하는 데 사용된다. 이 속성은 보통 MySQL, Oracle과 같은 DBMS에서 사용된다.
여기서는 employee_table이 company_db라는 카탈로그에 속하게 된다.@Entity @Table(name = "employee_table", catalog = "company_db") public class Employee { @Id private Long id; private String name; private String department; // Getters and Setters }
- uniqueConstraints:
- 이 속성은 테이블에 고유 제약 조건을 추가할 수 있습니다. 예를 들어, 여러 컬럼에 대해 고유 제약 조건을 설정하려면 이 속성을 사용한다.
이 예시에서는 name과 department 컬럼 조합에 대해 고유 제약 조건이 설정된다.@Entity @Table( name = "employee_table", uniqueConstraints = @UniqueConstraint(columnNames = {"name", "department"}) ) public class Employee { @Id private Long id; private String name; private String department; // Getters and Setters }
필드와 컬럼 매핑
어노테이션 설명 @Column 필드와 컬럼 매핑 @Temporal 날짜 타입 매핑 @Enumerated Enum 타입 매핑
- EnumType.ORDINAL: Enum 순서를 데이터베이스에 저장(0, 1..)
- EnumType.STRING: Enum 이름을 데이터베이스에 저장
항상 EnumType.STRING 사용해야함@Lob BLOB, CLOB 매핑 @Transient 특정 필드를 컬럼에 매핑하지 않음(매핑 무시) @Column
- 엔티티 클래스의 필드는 데이터베이스 테이블의 컬럼과 매핑된다.
- 기본적으로 필드 이름이 컬럼 이름과 일치하지만, `@Column` 어노테이션을 사용하여 매핑 정보를 세부적으로 설정할 수 있다.
@Entity public class Employee { @Id private Long id; @Column(name = "emp_name", nullable = false) private String name; // Getters and Setters }
여기서 `@Column(name = "emp_name")`는 name 필드를 `emp_name`이라는 컬럼에 매핑하고, `nullable = false`는 해당 컬럼이 NULL 값을 허용하지 않는 제약조건을 추가한 것이다.
@Temporal
- 날짜 타입을 매핑할 때 사용한다.
- 참고로 최근 버전에서는 `LocalDate`, `LocalDateTime` 타입을 사용하게 되면 해당 어노테이션을 사용하지 않아도 날짜 타입으로 설정된다.
@Enumerated
- Enum 타입을 매핑할 때 사용한다.
- Enum 타입을 사용하면 기본 값이 `EnumType.ORDINAL`이기 때문에 기본적으로 데이터베이스에서는 Integer 타입으로 설정된다.
- Enum 타입을 사용할 땐 `EnumType.STRING`으로 항상 설정해서 사용해야 한다.
@Lob
- Lob에는 지정할 수 있는 속성이 없다.
- 매핑하는 필드 타입이 문자면 CLOB 매핑, 나머지는 BLOB으로 매핑한다.
- CLOB: String, char[], java.sql.CLOB
- BLOB: byte[], java.sql.BLOB
@Transient
- 특정 필드를 데이터베이스 컬럼에 매핑하지 않는다.
- 주로 메모리 상에서만 임시로 어떤 값을 보관하고 싶을 때 사용한다.
🔹 예제 코드
현재 엔티티를 기준으로 어떻게 데이터베이스가 생성되는지 확인해보자.
물론 운영 환경에서는 직접 쿼리 스크립트를 작성하여 데이터베이스를 생성해야 한다.package hellojpa; import jakarta.persistence.*; import java.util.Date; // JPA가 관리할 객체 @Entity public class Member { @Id // 데이터베이스 PK와 매핑 private Long id; // DDL 생성 기능 @Column(unique=true, length = 10) private String name; 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; }
🔹 결과
현재 H2 데이터베이스 기준으로 다음과 같이 생성되었다. 위에서 설명한대로 모두 정상적으로 데이터 타입이 지정된 것을 확인할 수 있다.
결과 기본 키 매핑
연관관계 매핑
JPA에서는 엔티티 간의 관계를 매핑할 수 있다. 관계 매핑은 크게 1:1, 1:N, N:1, N:M 관계로 나눌 수 있다.
@OneToOne
두 엔티티가 1:1 관계일 때 사용한다. 예를 들어, 한 사람은 하나의 여권만 가질 수 있을 때 사용된다.
@Entity public class Person { @Id private Long id; @OneToOne @JoinColumn(name = "passport_id") private Passport passport; // Getters and Setters }
@OneToMany / @ManyToOne
`@OneToMany`와 `@ManyToOne`은 1:N, N:1 관계를 매핑할 때 사용한다. 예를 들어, 한 부서에 여러 직원이 있을 수 있고, 여러 직원은 한 부서에 속할 수 있다.
@Entity public class Department { @Id private Long id; @OneToMany(mappedBy = "department") private List<Employee> employees; // Getters and Setters } @Entity public class Employee { @Id private Long id; @ManyToOne @JoinColumn(name = "department_id") private Department department; // Getters and Setters }
@ManyToMany
`@ManyToMany`는 N:M 관계를 매핑할 때 사용한다. 예를 들어, 여러 학생이 여러 과목을 들을 수 있을 때 사용된다.
@Entity public class Student { @Id private Long id; @ManyToMany @JoinTable(name = "student_subject", joinColumns = @JoinColumn(name = "student_id"), inverseJoinColumns = @JoinColumn(name = "subject_id")) private List<Subject> subjects; // Getters and Setters }
@JoinColumn
데이터베이스 스키마 자동 생성
하이버네이트 설정 값(`hibernate.hbm2ddl.auto`)에 따라 DDL(Data Definition Language)을 애플리케이션 실행 시점에 자동 생성할지 결정한다.
- 운영 환경에서는 절대 `create`, `create-drop`, `update` 옵션을 사용하면 안된다.
- create, create-drop: 운영 데이터가 모두 날라간다.
- update: 테이블 수정이 이뤄지면 테이블 전체에 락이 발생할 수 있다. 락 발생 시 서비스 장애로 이어진다.
- 개발 초기 단계는 `create` 또는 `update` 사용
- 스테이징과 운영 서버는 `validate` 또는 `none` 사용
설정 값 목록
옵션 설명 create 기존 테이블 삭제 후 다시 생성(DROP + CREATE) create-drop create와 같으나 종료 시점에 테이블 DROP update 변경분만 반영 validate 엔티티와 테이블이 정상 매핑되었는지만 확인 none 사용하지 않음
DDL 생성 기능
아래와 같은 제약 조건을 엔티티에서 설정할 수 있는데 이것을 'DDL 생성 기능'이라고 한다.
DDL 생성 기능은 DDL을 자동 생성할 때만 사용되고, JPA의 실행 로직(런타임)에는 영향을 주지 않는다.
🔹 예제 코드
DDL 생성 기능을 통해 `name` 컬럼의 제약 조건을 추가했다.
package hellojpa; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; // JPA가 관리할 객체 @Entity public class Member { @Id // 데이터베이스 PK와 매핑 private Long id; // DDL 생성 기능 @Column(unique=true, length = 10) private String name; }
🔹 결과
테이블을 생성할 때 제약조건도 추가되는 것을 확인할 수 있다.
하이버네이트 설정 값(`hibernate.hbm2ddl.auto`)이 `create`가 아닌 `update` 옵션도 마찬가지로 제약조건이 추가된다.결과 다음글이 없습니다.이전글이 없습니다.댓글