API/JPA

Entity 매핑 #1

시뻘건 튼튼발자 2021. 1. 13. 15:24
반응형

JPA를 사용하면서 가장 중요한 일이 java의 entity와 database의 table을 매핑하는 것이라고 해도 과언이 아니다. 따라서 우리는 매핑 어노테이션을 충분히 알고 써야할 책임이 있다. JPA는 4가지의 매핑 어노테이션을 지원한다.

- 객체와 테이블 매핑 : @Entity, @Table

- 기본 키 매핑 : @Id

- 필드와 컬럼 매핑 : @Column

- 연관관계 매핑 : @ManyToOne, @JoinColumn

 

@Entity

테이블과 엔티티를 매핑할 때에는 필수로 사용해야한다. @Entity 어노테이션에서 지원하는 속성은 다음과 같이 정리할 수 있다.

속성 기능 default
name 엔티티 명 지정.
다른 패키지에 이름이 같은 엔티티 클래스가 있을 때 사용하여 충돌이 일어나지 않도록 한다.
클래스 명 그대로 사용

이 어노테이션을 적용하기 위해서는 조건이 있다.

1. public 혹은 protected의 기본 생성자

2. enum, interface, inner 혹은 final class는 사용 불가

3. 필드에 final 사용 불가

 

 

@Table

엔티티와 매핑할 테이블을 지정한다. 지원하는 속성을 정리하면 다음과 같다.

속성 기능 default
name 매핑할 테이블 이름 설정 엔티티 명 그대로 사용
catalog catalog 기능이 있는 데이터베이스에서 catalog 매핑  
schema schema 기능이 있는 데이터베이스에서 schema 매핑  
uniqueConstrains DDL 생성 시에 유니크 제약조건 생성.
 

 

상기 내용을 바탕으로 다음 java 코드를 살펴보자.

public enum RolrType {
	ADMIN, USER
}
@Entity
@Table(name="MEMBER")
public class Member {
	@Id
	@Column(name = "ID")
	private String id;
    
	@Column(name = "NAME")
	private String name;
    
	@Enumerated(EnumType.STRING)
	private RoleType roleType;
    
	@Temporal(TemporalType.TIMESTAMP)
	private Date createdDate;
    
	@Lob
	private String description;
}

처음 나오는 어노테이션에 대해 알아보자. (속성에 대해서는 다음 시간에 다루겠다.)

- java의 enum으로 매핑하기 위해서는 @Enumerated를 사용하여야한다.

- database의 timestamp를 매핑하기 위해서는 @Temporal을 사용하여야한다.

- database의 clob을 매핑하기 위해서는 @Lob을 사용한다. blob 타입도 매핑할 수 있다.

 

더보기

※ 이름 매핑 전략

보통 java에서는 카멜 표기법을 사용하며 데이터베이스에서는 언더스코어를 사용한다. 그렇기 때문에 @Column의 name속성을 사용하여 매핑을 이루게 되는데 이러한 수고를 덜 수 있는 방법이 있다.

hibernate.ejb.naming_strategy 설정으로 org.hibernate.cfg.ImprovedNamingStrategy를 주면 된다.

해당 설정 값은 테이블 명이나 컬럼 명이 생략되면 자바의 카멜 표기법을 언더스코어 표기법으로 매핑하게 한다.

 

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

JPA는 데이터베이스 스키마를 자동으로 생성할 수 있도록 설정할 수 있다. 개인적인 생각이지만 매핑을 완벽하게 할 수 있어야 안전하게 사용할 수 있을거라고 생각한다.

JPA를 사용하기 위한 설정과 동작 원리에서 언급했던 것과 같이 spring.jpa.hibernate.ddl-auto 속성을 통해 자동생성을 지원한다. 자동생성되는 DDL은 데이터베이스 방언에 따라서 달라질 수 있다.

  만약 이 기능을 사용하면 개발자가 직접 테이블을 만드는 시간을 절약할 수 있다. 그러나 개발 외에 운영 환경에서 사용할 만큼 완벽하지 않기 때문에 참고하는 정도로 사용하는 것으로 권장하고 있다.

  DDL 자동생성에 대해 몇몇 제약조건이 따를 수 있다. 다음과 같이 java 코드를 살펴보자.

@Entity
@Table(name="MEMBER", uniqueConstraints = {@UniqueConstraint(name="NAME_AGE_UNIQUE", columnNames = {"NAME", "AGE"})})
public class Member {
	@Id
	@Column(name = "ID")
	private String id;
    
	@Column(name = "NAME", nullable = false, length = 10)
	private String name;
    
	@Enumerated(EnumType.STRING)
	private RoleType roleType;
    
	@Temporal(TemporalType.TIMESTAMP)
	private Date createdDate;
    
	@Lob
	private String description;
}

JPA를 사용하기 위한 설정과 동작 원리에서 언급했지만 @Column에 대한 속성으로 제약조건을 줄 수 있다.

@Table의 uniqueConstraints 속성에 대해 알아보자. 상기 내용에 대해 생성된 DDL은 다음과 같다.

ALTER TABLE MEMBER
ADD CONSTRAINT NAME_AGE_UNUQUE
UNUQUE (NAME, AGE)

유니크 제약조건을 추가한 것이다. 이러한 속성은 DDL을 자동생성할 때 사용되며 JPA의 실행 로직에는 아무런 영향을 주지 않는다. 이 말은 DDL 자동생성을 사용하지 않는다면 이러한 속성도 사용할 필요도 없다는 이야기다. 그러나 코드만 보고도 테이블을 머릿 속에 그릴 수 있기 때문에 제약조건 등을 파악할 수 있는 좋은 점도 있다.

반응형