쿠릉쿠릉 쾅쾅
쿠릉쿠릉 쾅쾅
쿠릉쿠릉 쾅쾅
250x250
전체 방문자
오늘
어제
  • 분류 전체보기
    • HTML CSS
    • 잡담
    • 프로그래밍 꿀팁 사이트
    • 코딩 도서
    • [자바]
      • 디자인 패턴
      • 자바의 정석 - 3판
      • 자바
      • 자바 문법
    • git
    • [TDD]
    • 개발 서적 독후감
      • 클린 코더
      • 토비 스프링3
      • 객체지향의 사실과 오해
      • 모던 자바 인 액션
      • 엘레강트 오브젝트
    • CS
      • 운영체제
      • HTTP
    • [SQL]
      • SQL 기초
      • 혼자공부하는SQL
    • [ Spring ]
      • REST API
      • Spring Toy
      • Spring 에러
      • Spring
      • Spring 입문
      • Spring 핵심 원리
      • SpringMVC 1편
      • SpringMVC 2편
      • Spring Boot를 이용한 RESTful We..
      • Batch
    • [JPA]
      • JPA
      • JPA 에러
      • JPA 프로그래밍 - 기본편
      • 스프링 부트와 JPA 활용 1 - 웹 애플리케이..
      • 실전! 스프링 부트와 JPA 활용2 - API 개..
      • 실전! 스프링 데이터 JPA
      • 실전! Querydsl
    • 인텔리제이
    • [DB]
      • DB
      • H2
    • Gradle
    • 면접
    • [알고리즘]
      • 알고리즘
      • 자료구조
      • 자바 알고리즘 공부
    • [프로젝트]
    • 쿠릉식 객체지향 사고
    • 리눅스

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • http
  • 자료구조
  • 깃허브
  • querydsl
  • SQL
  • 스프링
  • 알고리즘
  • 백준
  • GitHub
  • java
  • 함수형인터페이스
  • JPA
  • 재귀
  • springboot
  • REST API
  • 자바
  • 스프링부트
  • Git
  • MVC
  • Spring

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
쿠릉쿠릉 쾅쾅

쿠릉쿠릉 쾅쾅

[JPA]/JPA 프로그래밍 - 기본편

[JPA] 엔티티 매핑

2022. 3. 27. 02:51
728x90

 

엔티티 매핑 소개

  • 객체와 테이블 매핑 : @Entity / @Table
  • 필드와 칼럼 매핑 : @Column
  • 기본 키 매핑 : @Id
  • 연관관계 매핑 : @ManyToOne / @JoinColumn

 


 

객체와 테이블 매핑

 

1. @Entity

  • @Entity 애노테이션이 붙은 클래스는 JPA가 관리한다.
  • 엔티티라고 부른다.
  • JPA를 사용해서 테이블과 매핑할 클래스에는 @Entity를 무조건 붙여야 한다.
  •  주의
    • 기본 생성자가 필수다.
      • 파라미터가 없는 public 또는 protected 생성자가 존재해야한다.
      • JPA가 객체를 동적으로 사용하거나 프록싱 기술을 쓰기 위해선 기본 생성자가 필요하기 때문이다.
    • final 클래스 / enum / interface / inner 클래스에는 @Entity 애노테이션을 사용할 수 없다.
    • DB에 저장할 필드값에 final 을 붙이면 안된다.

🔍 주의 사항

  • 기본 생성자가 무조건 정의되어 있어야 한다.
    • 파라미터가 없는 public 또는 protected 생성자가 존재해야한다.
    • JPA가 객체를 동적으로 사용하거나 프록싱 기술을 쓰기 위해선 기본 생성자가 필요하기 때문이다.

🔍 @Entity 속성

name 속성

  • JPA에서 사용할 엔티티 이름을 지정한다.
  • 기본값: 클래스 이름을 그대로 사용한다.
    • 예) Member

name 속성 사용 예시

@Entity(name = "hello")
public class Member {...}
  • 같은 클래스 이름이 없으면 name 속성을 쓰기 보단 가급적 기본값을 사용하는 것이 좋다.

 

2. @Table

  • @Table 애노테이션은 엔티티와 매핑할 테이블을 지정한다.

🔍 @Table 속성

속성  기능 기본 값
name 매핑할 테이블 이름 지정 엔티티 이름을 사용한다.
catalog 데이터베이스 catalog 매핑  
schema 데이터베이스 schema 매핑  
uniqueConstraints (DDL) DDL 생성 시에 유니크 제약 조건 생성  

 

 

 


 

데이터베이스 스키마(schema) 자동 생성

  • 데이터베이스 스키마 자동생성 기능은 객체에 정의한 정보를 바탕으로 테이블을 만들어주는 기능이다.
  • JPA는 데이터베이스 스키마를 자동으로 생성하는 기능을 지원한다.
    • 애플리케이션 실행 시점에 DB 테이블을 생성하는 기능이다.
  • 데이터 스키마 자동 생성 기능은 운영 서버에선 절대 사용하면 안된다.
  • 개발 단계 또는 로컬 PC일 때만 사용할 것을 권장한다.
  • JPA는 데이터베이스 방언을 활용해서 데이터베이스에 맞는 적절한 DDL을 생성해준다.
  • 이렇게 생성된 DDL은 개발 서버에서만 사용할 것. 운영서버에 사용하면 안된다.
  • 생성된 DDL을 운영서버에 굳이 사용한다면 다듬고 사용할 것.

 

1. 데이터베이스 스키마 자동 생성 속성

🔍 hibernate.hbm2ddl.auto

옵션 설명
create  기존 테이블을 삭제 후 다시 생성한다. (DROP + CREATE)
create-drop  create와 같으나 종료시점에 테이블을 DROP 한다.
update 변경 부분만 반영한다. (절대 운영 DB에 사용하면 안된다.)
변경 부분이 필드 추가일 때만 적용된다. 필드 삭제인 경우 적용 안됨. 
validate 엔티티와 테이블이 정상 매핑되었는지만 확인한다.
none 아무 기능도 사용하지 않는다.

🔍 사용 방법

<property name="hibernate.hbm2ddl.auto" value="create" />
  • persistence.xml 파일에서 추가하면 된다.

🧷 참고. 스키마 (schema)

  • 스키마는 데이터베이스 구조를 의미한다.
  • 정확히 말해서 개체의 특성을 나타내는 속성(Attribute)과 속성들의 집합으로 이루어진 개체(Entity), 개체 사이에 존재하는 관계(Relation)에 대한 정의와 이들이 유지해야할 제약 조건을 기술한 것이다.

🧷 참고. DDL (Data Definition Language)

  • 객체의 생성, 변경, 삭제 명령어를 의미한다.
  • 예를 들어 create / alter / drop / rename 등이 있다.
  • shcema, domain, table, view, index를 정의, 변경 삭제할 때 사용하는 언어다.
  • 한마디로 데이터베이스의 스키마(테이블 명, 열 이름 등)를 만들어주는 SQL문 집합이다.

 

2. 스키마 사용시 주의사항

  • 운영 서버에 절대 create / creat-drop / update 속성을 사용하면 안된다.
  • 개발 초기 단계 (나 홀로 개발)인 경우에는 create 또는 update 속성 정도는 사용해도 된다.
  • 테스트 서버 단계 (여러 개발자와 협업)에서는 update 또는 validate 속성 정도는 사용해도 된다.
  • 스테이징과 운영 서버에는 validate 또는 none 속성 정도만 사용할 것.
  • 사실 모든 서버에 none 속성이 제일 좋다. 그냥 이 기능을 안쓰는 것을 권장한다.
  • 스키마를 사용하는 것 보다 본인이 직접 스크립트를 작성해서 적용하는 것이 좋다.

 

3. DDL 생성 기능

  • 제약 조건 추가 : ex) 회원 이름은 필수, 10자 초과 X
    • @Column(nullable = false, length = 10)
  • 유니크 제약 조건 추가
    • @Table(uniqueConstraints = {@UniqueConstraint( name = "NAME_AGE_UNIQUE", columnNames = {"NAME", "AGE"} )}) 
  • DDL 생성 기능은 DDL을 자동 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않는다.

 


 

필드와 컬럼 매핑

package hellojpa;


import javax.persistence.*;
import java.util.Date;

@Entity
public class Member {

    public Member() {
    }

    @Id
    private Long id;

    @Column(name = "name")
    private String username;

    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;

    @Transient
    private String temp;

}
  • 위 코드에서 RoleType 타입은 개발자가 직접 만든 Enum 클래스 타입이다.

 

1. 매핑 어노테이션 종류

어노테이션 설명
@Column 컬럼(속성) 매핑
@Temporal 날짜 타입 매핑
@Enumerated enum 타입 매핑
@Lob BLOB / CLOB 매핑
@Transient 특정 필드를 컬럼에매핑하지 않는다. (매핑 무시)

 

2. @Column

  • 컬럼을 매핑할 때 사용한다.
속성 설명 기본 값
name - 필드와 매핑할 테이블의 컬럼 이름 객체의 필드 이름
insertable
updatable
- 등록 가능 여부
- 변경 가능 여부
TRUE
nullable (DDL) - null 값의 허용 여부를 설정한다.
- false로 설정하면 DDL 생성 시에 not null 제약 조건이 붙는다.
- 자주 쓰인다.
 
unique (DDL) - @Table의 uniqueConstraints와 같지만 한 컬럼에 간단히 유니크 제약 조건을 걸 때 사용한다.
- 자주 안쓰인다. → 제약 조건의 이름이 너무 난수값이라 알아보기 힘들기 때문
- @Table(uniqueConstraint())에 사용하는 것을 권장한다.
 
columnDefinition (DDL) - 데이터베이스 칼럼 정보를 직접 줄 수 있다.
- ex) varchar(100) defualt 'EMPTY'
필드 자바 타입과 방언 정보를 사용
length (DDL) - 문자 길이 제약 조건.
- String 타입에만 사용한다.
255
percision
scale (DDL)
- BigDecimal 타입에 사용한다. (BigInteger타입도 사용 가능)
- percision은 소수점을 포함한 전체 자릿수다.
- scale은 소수의 자릿수다.
- 참고로 double, float 타입에는 적용되지 않는다.
- 아주 큰 숫자나 정밀한 소수를 다룰 때 사용한다.
percision = 19
scale = 2

 

3. @Enumerated

  • 자바 enum 타입을 매핑할 때 사용한다.
속성 설명 기본 값
value EnumType.ORDINAL : enum 순서를 데이터베이스에 저장
EnumType.STRING : enum 이름을 데이터베이스에 저장
EnumType.ORDINAL
  • 무조건 EnumType.STRING 으로 사용할 것.
    • enum 타입이 추가 / 변경 / 삭제가 되어 순서가 달라질 경우 사이트 이펙트가 생긴다.

 

4. @Temporal

  • 날짜 타입(java.util.Date, java.util.Calendar)을 매핑할 때 사용한다.
  • 지금은 잘 안쓰인다.
  • 왜냐하면 LocalDate(년월), LocalDateTime(년월일)을 사용할 때는 생략이 가능하다. (최신 하이버네이트에서 지원한다.)
속성 설명 기본 값
value - TemporalType.DATE : 날짜, 데이터베이스 date 타입과 매핑 (예 : 2012-10-11)
- TemporalType.TIME : 시간, 데이터베이스 time 타입과 매핑 (예 : 10:06::22)
- TemporalType.TIMESTAMP : 날짜와 시간, 데이터베이스 timestamp 타입과 매핑
(예 : 2013-10-11 11:05:35)
 

 

5. @Lob

  • 데이터베이스 BLOB / CLOB 타입과 매핑한다.
  • @Lob 어노테이션에는 지정할 수 있는 속성이 없다.
  • 매핑하는 필드 타입이 문자(String / char[])면 CLOB으로 매핑된다.
  • 나머지는 BLOB으로 매핑된다.

 

6. @Transient

  • 필드 매핑을 하고 싶지 않을 때 사용한다.
  • 데이터베이스에 저장과 조회를 하지 않는다.
  • 주로 메모리상에만 임시로 어떤 값을 보관하고 싶을 때 사용한다.

 


 

기본 키 매핑

1. 기본 키 매핑 어노테이션

  • @Id
  • @GeneratedValue
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

 

2. 기본 키 매핑 방법

  • 직접 할당 : @Id 애노테이션만 사용
  • 자동 생성 : @Id 애노테이션 + @GeneratedValue 애노테이션 둘 다 사용

🔍 PK 값 직접 할당 

  • @Id 애노테이션만 사용한다.
@Id
privat Long id;

🔍 PK 값 자동 생성

  • @Id 애노테이션, @GeneratedValue 애노테이션 같이 사용한다.
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
  • @GeneratedValue 애노테이션을 사용할 때 strategy 속성 값을 지정할 수 있다.
    • IDENTITY
    • SEQUENCE
    • TABLE
    • AUTO

✔ IDENTITY

  • PK 값 생성을 데이터베이스에 위임한다.
  • 주로 MySQL / PostgreSQL / SQL Server / DB2 / MariaDB 에서 사용한다.
  • JPA는 보통 트랜잭션 커밋 시점에서 INSERT SQL 구문을 DB에 전달한다.
  • 하지만 AUTO_INCREMENT는 DB에 INSERT SQL을 실행 한 후에 PK 값을 알 수 있다.
  • 그렇기에 IDENTITY 속성값은 사용할 경우 em.persist() 가 호출될 때 바로 INSERT 쿼리가 DB에 전달된다.
    • 쓰기 지연 기능을 사용할 수 없다.
    • 애초에 쓰기 지연 기능이 성능을 획기적으로 좋게 하지 않기에 IDENTITY를 사용해도 성능 이슈가 없다.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

✔ SEQUENCE

  • 데이터베이스의 시퀀스 오브젝트(Sequence Object)를 사용하여 데이터베이스가 자동으로 pk 값을 생성해준다.
  • 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트다.
  • @SequenceGenerator 애노테이션이 필요하다.
    • 테이블마다 시퀀스 오브젝트를 따로 관리하고 싶으면 @SequenceGenerator에 sequenceNmae 속성을 추가한다.
  • 주로 ORACLE / PostgreSQL / DB2 / H2 데이터베이스에서 사용한다.
  • SEQUENCE 전략은 pk값을 설정하지 않고 generator에 매핑된 Sequence 전략에서 pk값을 얻는다.
    • 해당 Sequence Object는 DB가 관리하기 때문에 DB에서 id값을 가져와야 한다.
  • em.persist()를 호출하기 전에 DB의 Sequence에서 pk값을 가져온다.
    • DB에서 계속 pk 값을 얻으려고 접근을 시도하면 성능 하락이 있을 수 있다.
    • 따라서 initialValue 속성 값을 1로 맞추고, allocationSize를 속성을 사용하여 DB를 접근할 때 한꺼번에 많은 pk 값들을 가져와서 메모리에 저장한다.
    • em,persist()가 호출될 때 영속성 컨텍스트에 엔티티가 저장될 때 마다 메모리에서 가져온 pk 값을 조회하여 순차적으로 반환 받는다.
    • 만약에 메모리에서 pk 값을 다 사용했으면 또 다시 DB에 접근하여 또 한꺼번에 많은 pk값들을 가져와서 메모리에 저장한다.  
    • 그렇게 하여 성능 이슈를 해결했다. 동시성 문제도 없다.
@Entity
@SequenceGenerator(
        name = “MEMBER_SEQ_GENERATOR",
        sequenceName = “MEMBER_SEQ", //매핑할 데이터베이스 시퀀스 이름
        initialValue = 1, allocationSize = 1)
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
            generator = "MEMBER_SEQ_GENERATOR")
    private Long id;

@SequenceGenerator 애노테이션 속성

속성 설명 기본 값
name - 식별자 생성기 이름 필수
sequenceName - 데이터베이스에 등록되어 있는 시퀀스 이름 hiberante_sequence
initialValue - DDL 생성 시에만 사용된다.
- 시퀀스 DDL을 생성할 때 처음 시작하는 수를 지정한다.
1
allocationSize - 시퀀스 한 번 호출에 증가하는 수를 의미한다. (성능 최적화에 사용된다.)
- 데이터 베이스 시퀀스 값이 하나씩 증가하도록 설정되어 있으면 이 값을 반드시 1로 설정해야 한다.
50
catalog
schema
- 데이터 베이스 catalog 이름
- 데이터 베이스 schema 이름
 

✔ TABLE

  • 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략이다.
  • @TableGenerator 애노테이션이 필요하다.
  • 장점 : 모든 데이터베이스에 적용 가능
  • 단점 :  성능 이슈
    • 시퀀스 오브젝트는 숫자 뽑는데 최적화가 되어있지만 테이블은 최적화가 안되어 있다.
    • 별도의 테이블을 생성했을 지라도 락이 걸릴 수 있어 성능의 이슈가 있다.
    • 운영 서버에 TABLE 전략을 쓰면 안된다.
  • 자주 안쓰인다.

@TableGenerator 속성

속성 설명 기본 값
name 식별자 생성기 이름 필수
table 키생성 테이블명 hibernate_sequences
pkColumnName 시퀀스 컬럼명 sequence_name
valueColumnNa 시퀀스 값 컬렴명 next_val
pkColumnValue 키로 사용할 값 이름 엔티티 이름
initalValue 초기 값. 마지막 으로 생성된 값이 기준이다. 0
allocationSize 시퀀스 한 번 호출에 증가하는 수
성능 최적화에 사용된다.
50
catalog
schema
데이터 베이스 catalog 이름
데이터베이스 schema 이름
 
uniqueConstraint (DDL) 유니크 제약 조건을 지정할 수 있다.  

✔ AUTO

  • 데이터베이스 방언에 따라 자동 지정한다.
  • 기본값이다.

 

3. 권장하는 식별자 전략

  • 기본 키(pk)의 제약 조건
    • pk 값이 null 값이면 안된다. : not null
    • pk 값이 유일한 값을 가져야 한다. : unique
    • pk 값이 변하면 안된다. : not update
  • 비즈니스적으로 의미있는 키를 pk로 하지 않는 것이 좋다. 의미 없는 값을 pk값으로 하는 것이 좋다.
  • 기본 키의 제약조건 다 만족하는 기본 키값을 찾기 힘들기 때문에 대리키(대체키)를 사용하도록 한다.
  • PK 값 권장 방법
    • Long 타입 형 + 대체키 + 키 생성 전략 사용
      • 대체키를 uuid로 해도 된다.

 

 

 

 


👀 참고자료

https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

 

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

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

www.inflearn.com

 

https://iingang.github.io/posts/DB-schema/

 

[DB 데이터베이스] 스키마(Schema)의 개념 및 특징

Contents

iingang.github.io

 

https://jjeongil.tistory.com/1230?category=688419 

 

SW 면접 : 데이터 베이스 : DDL, DML, DCL 개념과 차이점

DDL (Data Definition Language) 객체의 생성, 변경, 삭제 명령어를 뜻합니다. 예를 들어, create, alter, drop, rename 등이 있습니다. schema, domain, table, view, index를 정의, 변경, 삭제할 때 사용하는..

jjeongil.tistory.com

 

https://catsbi.oopy.io/f03397e5-a900-4f1c-956f-fc660a1ac3c5

 

엔티티 매핑

객체와 테이블 매핑

catsbi.oopy.io

 

728x90

'[JPA] > JPA 프로그래밍 - 기본편' 카테고리의 다른 글

[JPA] 다양한 연관관계 매핑  (0) 2022.03.29
[JPA] 연관관계 매핑 기초  (0) 2022.03.28
[JPA] 영속성 관리 - 내부 동작 방식  (0) 2022.03.26
[JPA] JPA 시작하기  (0) 2022.03.26
[JPA] SQL 중심적인 개발의 문제점과 JPA 소개  (0) 2022.03.26
    '[JPA]/JPA 프로그래밍 - 기본편' 카테고리의 다른 글
    • [JPA] 다양한 연관관계 매핑
    • [JPA] 연관관계 매핑 기초
    • [JPA] 영속성 관리 - 내부 동작 방식
    • [JPA] JPA 시작하기
    쿠릉쿠릉 쾅쾅
    쿠릉쿠릉 쾅쾅
    깃허브 주소 : https://github.com/kureung

    티스토리툴바