본문 바로가기
  • 개발공부 및 일상적인 내용을 작성하는 블로그 입니다.
JPA

객체와 테이블 간 Entity 매핑

by 방구석 대학생 2020. 9. 19.

"인프런 - 자바 ORM 표준 JPA 프로그래밍 강의를 듣고 작성한 글 입니다."

www.inflearn.com/course/ORM-JPA-Basic#

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다. 초급 웹 개발 프로그

www.inflearn.com

 

- 실제 설계적인 측면에서, 객체와 관계형 데이터베이스를 어떻게 매핑해서 사용할 수 있을까?

우선 유용하게 사용할 수 있는 객체와 테이블간 Entity 매핑 어노테이션은 아래와 같다.

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

- 필드와 컬럼 매핑 : @Column

- 기본 키 매핑 : @Id, @GeneratedValue

- 연관관계 매핑 : @ManyToOne, @JoinColumn (Member 와 Team 도메인 간에 1 : 1, 1 : N 과 같은 연관관계가 있을 때 어떻게 매핑을 해야할까?)

 

 

@Entity 어노테이션

객체와 테이블을 매핑하기 위해 먼저 자바 클래스와 테이블간의 매핑이 필요하다.

JPA 에서는 위의 @Entity 어노테이션이 중요하다. 해당 어노테이션이 붙어있는 클래스는 JPA 가 관리하는 Entity 라는 뜻이다.

위의 어노테이션이 붙어 있지 않은 클래스는 JPA 와 전혀 관계없이 개발자 본인이 마음대로 쓰고자 해서 만든 클래스로 보면 된다.

JPA 를 사용해서 테이블과 매핑할 클래스는 위의 어노테이션이 필수이다.

 

* 주의할 점

- 기본 생성자(default constructor - parameter 가 없는 public, 또는 protected 생성자) 는 필수 이다.(JPA 스펙상으로 규정되어 있다.)

   -> JPA 를 구현해서 사용하는 라이브러리 들이 리플렉션, 프록싱과 같이 동적인 기능들을 수행하기 위해서 필요하다. 

- final 클래스, enum, interface, inner 클래스는 사용하지 않는다.

- 데이터베이스에 저장하고 싶은 필드에는 final 키워드를 사용하면 안된다.

 

@Entity 어노테이션 속성

- name 속성

: JPA 에서 사용할 Entity 의 이름을 지정한다.(JPA 가 내부적으로 구분하기 위한 이름)

기본값은 현재 클래스의 이름과 동일하다. 일반적으로 사용할 일은 없으나 다른 패키지에 같은 이름의 클래스가 있는 경우 하나는 다른 이름을 써줘야 하기 때문에 name 속성을 활용할 수 있다.

같은 클래스 이름이 없으면 가급적 기본값을 사용한다.

 

@Entity // JPA 가 관리하는 클래스임을 알리는 어노테이션 
public class Memeber{
 // .......
}

 

 

@Table 어노테이션

: 테이블을 다른 이름으로 매핑해야 하는 경우 활용할 수 있다.

(예 : 개발 시 회사에서 테이블의 명을 직접 지정해준 경우)

- name 속성을 활용하여 매핑할 테이블의 이름을 지정해 줄 수 있다.

 

 

- 데이터베이스 스키마를 자동으로 생성해보자.

JPA 는 매핑 정보만 보면 어떤 SQL 쿼리를 만들어야 할지, 어떤 테이블인지 알 수 있다.

그래서 JPA 는 아예 애플리케이션 로딩 시점에 DB 테이블을 생성하는 기능을 지원해준다.(DDL 을 애플리케이션 실행 시점에 자동 생성)

(이건 운영에서 쓰는게 아니라, 개발 단계나 로컬 PC 에서 개발할 때 도움이 되는 기능이다.)

 

애플리케이션 로딩 시점에 create 문으로 DB 를 생성하고 시작하게 할 수 있다.

SQL 을 작성하여 직접 테이블을 생성할 필요 없이 JPA 는 객체와 테이블간의 매핑을 해 놓으면 필요 시 테이블을 직접 생성해준다.

데이터베이스 방언을(dialect) 활용해서 데이터베이스에 맞는 적절한 DDL 을 생성해 줄 수 있으나, 이렇게 생성된 DDL 은 반드시 개발 단계에서만 사용해야 한다.(운영 단계에서 사용하면 큰일 난다.)

 

- 그렇다면 어떻게 자동으로 스키마를 생성해줄 수 있을까?

JPA 옵션 설정 파일 persistence.xml 파일에 아래와 같은 옵션을 추가해준다.

<property name = "hibernate.hbm2ddl.auto" value = "create" />

 위의 옵션에서와 같이 옵션의 value 값을 create 로 해 놓은 후 애플리케이션을 로딩 시키면 아래와 같은 Hibernate message 및 SQL 문을 확인할 수 있다.

Hibernate: 
    
    drop table if exists Member CASCADE // Member 테이블이 존재할 시 삭제하라
Hibernate: 
    
    create table Member ( // 테이블 생성
       id bigint not null,
        name varchar(255),
        primary key (id)
    )

 

-> 기존에 테이블이 존재한다면 해당 테이블을 drop 문을 통해 삭제한 후 새로 생성한다.

필드를 하나 새로 추가한 이후 다시 애플리케이션을 로딩시키면 해당 필드가 추가된 테이블로 다시 생성해준다.

(물론 기존에 있던 테이블은 삭제된다.)

보통같은 경우 SQL 까지 함께 직접 작성해서 테이블을 만들어주어야 하는데, 그런 번거로움 없이 JPA 가 직접 해결해준다.

 

- create 이외의 다른 옵션?

create-drop 옵션 : create 과 같으나, 애플리케이션 종료시점에 테이블을 drop 한다.

해당 옵션은 테스트 케이스 실행 이후 마지막에 깔끔하게 테이블 들을 날려버리고 싶을 때 사용할 수 있다.

 

update 옵션 : 변경분 만 반영해주는 옵션이다.(운영 DB 에서는 사용하면 안된다.)

기존에 있던 테이블을 drop 이 아닌 alert 를 이용하여 테이블의 스키마를 변경시켜 줄 때 사용한다.

이미 존재하는 필드를 지웠을 때는 아무 SQL 문도 실행시키지 않는다.(필드 삭제의 경우 잘못하면 정말 큰일 날 수 있음)

 

validate 옵션 : Entity 와 테이블이 정상 매핑되었는지 확인해준다.

정상적으로 매핑되지 않았을 경우 오류가 발생한다.(필드의 이름이 맞지 않는 경우 등)

 

none 옵션 : 어떤 기능도 사용하지 않는다.(아예 생략시켜도 상관없으나 관례상 사용함)

 

* 주의할 점!

- 운영 장비에는 절대로 create, create-drop, update 를 사용하면 안된다.(정말 큰 사고 날 수 있음)

- 개발 초기 단계에는 create 또는 update 를 통해 본인 로컬 또는 개발서버에서 사용하면 된다.

- 테스트 서버(어느정도 개발이 진행된 단계) 에서는 update 또는 validate 를 활용할 수 있다.

   -> 보통 여러명의 개발자 들이 함께 사용하는 테스트 서버를 말하는데, 여기에 create 를 사용하면 그동안 했던 테스트 케이스들이 전부 날아갈 수도 있다.

- 스테이징과 운영서버는 validate 또는 none 을 활용한다.

 

사실 테스트 서버나 개발 서버도 가급적이면 위의 옵션들을 쓰지 않는 것이 좋다.(운영 서버는 특히 더)

개발 서버랑 스테이징 서버는 validate 까지는 괜찮은 것 같다고도 한다.

왜냐하면 개발 서버 같은 경우 update 를 하면 편할 것이나, 결국 운영 같은 경우 데이터가 굉장히 많은 상태에서 alert 를 잘못 치거나 하면 시스템이 중단상태가 될 수도 있다.

 

그런데 이걸 애플리케이션 로딩 시점에 시스템이 자동으로 alert 를 쳐 준다는게 굉장히 위험하다.(5분 정도만 시스템이 멈춰도 큰 장애가 발생하는 것이라고 볼 수 있다.)

그래서 가급적이면 alert 와 같은 스크립트를 직접 만든걸 테스트 서버에 한번 반영을 해봐야 한다.

테스트 서버나 개발 서버도 가급적이면 직접 스크립트를 짜서 적용해보는 것을 권장한다.

(문제 없으면 운영 서버에도 DBA 분께 전달해서 검수를 받고 적용하는 것을 권장한다.)

로컬 PC 에서는 자유롭게 하되, 여러명이 함께 쓰는 서버의 경우는 권장하지 않는다.

 

 

- DDL 생성 기능

- 제약 조건을 추가할 수 있다.

예시 : 유니크 제약 조건, 길이는 10자를 초과하면 안된다.

@Column(unique = true, length = 10)

위와 같이 @Column 어노테이션으로 제약 조건을 걸었을 때 hibernate 에서는 어떤식으로 SQL 문을 작성해줄까?

 

Hibernate: 
    
    create table Member (
       id bigint not null,
        name varchar(10), // 길이 제약조건 : 10자를 초과하면 안됨
        primary key (id)
    )
Hibernate: 
    
    alter table Member 
       add constraint UK_ektea7vp6e3low620iewuxhlq unique (name) 
       // unique 제약조건 - 애플리케이션이 아닌 데이터베이스에 영향을 준다.(JPA 의 실행 매커니즘에 영향을 주는게 아님)

 

위와 같은 unique 제약조건은 alter table 과 같은 DDL 생성만 도와준다. (즉, 실행 자체에 영향을 주지 않음)

-> DDL 생성 기능은 DDL 을 자동 생성할 때만 사용되고 JPA 의 실행 로직에는 영향을 주지 않는다.

'JPA' 카테고리의 다른 글

필드와 컬럼 매핑 - 2  (0) 2020.09.19
필드와 컬럼 매핑 - 1  (0) 2020.09.19
준영속 상태에 대하여....  (0) 2020.09.12
플러시(flush) 에 대하여...  (0) 2020.09.11
영속성 컨텍스트의 이점 - 변경 감지, 엔티티 삭제  (0) 2020.09.09