엔티티 매핑
- 엔티티 매핑
- 객체와 테이블 매핑 : @Entity, @Table
- 필드와 컬럼 매핑 : @Column
- 기본 키 매핑 : @Id
- 연관관계 매핑 : @ManyToOne, @JoinColumn
객체 - 테이블 매핑
- @Entity : @Entity가 붙은 클래스는 JPA가 관리하는 엔티티이다.
- JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 필수
- 기본 생성자 필수 생성
- final 클래스, enum, interface, inner 클래스에는 @Entity를 붙일 수 없다.
- 저장할 필드에 final 사용 x
- @Entity 속성
- name : JPA에서 사용할 엔티티 이름을 지정한다.
기본값은 클래스명으로 같은 클래스명이 없으면 가급적 기본값으로 사용
- name : JPA에서 사용할 엔티티 이름을 지정한다.
- @Table : 엔티티와 매핑할 테이블을 지정한다.
- @Table과 @Entity의 차이
- @Entity만 사용하는 경우 => 엔티티 이름 지정 + 데이터베이스 테이블 이름 지정
- @Entity와 @Table을 함께 사용하는 경우 => @Entity는 엔티티 이름만 지정, @Table은 데이터베이스 테이블 이름만 지정
데이터베이스 스키마 자동 생성
//persistence.xml 파일 옵션으로 지정
<property name="hibernate.hbm2ddl.auto" value="create" /> //DDL 자동 생성
- 데이터베이스 스키마 자동 생성
- 애플리케이션 실행 시점에 DDL(DB)을 자동 생성할 수 있다.
- 테이블 중심 설계 -> 객체 중심 설계를 할 수 있다.
- 데이터베이스 방언을 활용해서 DB에 맞는 적절한 DDL 생성
- 자동 생성으로 생성된 DDL은 운영서버가 아닌 개발 시에만 사용할 것.
- 애플리케이션 실행 시점에 DDL(DB)을 자동 생성할 수 있다.
- 데이터베이스 스키마 자동 생성 - 속성
- create : 기존 테이블 삭제 후 다시 생성 (DROP + CREATE)
- create-drop : create와 같으나 종료시점에 테이블 DROP
- 주로 테스트 케이스 실행 후 데이터를 제거하고 싶을 때 사용한다.
- update : 변경분만 반영 (운영 DB에서 사용x)
- 테이블 컬럼을 추가하는 것은 되지만 삭제하는 것은 안된다.
- validate : 엔티티와 테이블이 정상 매핑되었는지만 확인
- none : 사용하지 않음
- 데이터베이스 스키마 자동 생성 - 주의할 점
- 운영 장비에는 절대 create, create-drop, update를 사용하면 안된다.
- 개발 초기 단계 - create 또는 update
- 테스트 서버 - update 또는 validate
- 스테이징과 운영 서버 - validate 또는 none
- 로컬 PC에서 개발 시 자동 생성을 통해 사용하고 자동 생성 스크립트를 확인하고 다듬어서 운영 서버에서 사용하는 것이 좋다.
- DDL 생성 기능 : DDL을 자동 생성할 때만 사용되고 JPA 실행 로직에는 영향을 주지 않는다.
- 제약조건 추가 - @Column(nullable = true/false , length = ... , unique = true/false)
- nullable 속성 : 해당 컬럼의 NULL 값을 허용할지 말지 지정할 수 있다.
- length 속성 : 해당 컬럼의 길이 제한을 둘 수 있다.
- unique 속성 : 해당 컬럼 데이터의 유일성을 지정할 수 있다.
- 제약조건 추가 - @Column(nullable = true/false , length = ... , unique = true/false)
필드 - 컬럼 매핑
- 필드 - 컬럼 매핑
- @Column : 컬럼을 매핑하기 위해서 사용된다.
- @Enumerated : ENUM 타입 필드를 테이블 컬럼에 매핑시키기 위해서 사용된다.
- 값으로 EnumType.ORDINAL(기본값)과 STRING이 있다.
- ORDINAL은 enum 순서를 데이터베이스에 저장한다.
- STRING은 enum 이름을 데이터베이스에 저장한다.
- ORDINAL을 사용하면 안되고 필수적으로 STRING을 사용해야한다!!
- 순서로 저장되기 때문에 ENUM 값이 추가되는 경우 꼬일 수 있다.
- @Temporal : 날짜, 시간 타입 필드를 테이블 컬럼에 매핑시키기 위해서 사용된다.
- DB 타입에는 날짜, 시간, 날짜+시간 타입이 별도로 존재한다.
- LocalDate, LocalDateTime 사용 시 생략 가능
- @Lob : 가변 길이를 갖는 큰 데이터를 저장하기 위해서 사용된다.
- 데이터베이스 BLOB, CLOB 타입과 매핑된다.
- 별도로 지정할 속성은 없다.
- 매핑하는 필드 타입이 문자면(String, char ...) CLOB 매핑
- 나머지는 BLOB 매핑
- @Transient : 특정 필드를 컬럼에 매핑하지 않기 위해서 사용된다.
- 데이터베이스에 저장되지 않고 조회되지 않는다.
- 주로 메모리상에서만 임시로 값을 보관하고 싶을 때 사용한다.
- @Column 속성
- name - 필드와 매핑할 테이블의 컬럼 이름 (기본값 : 필드명)
- insertable, updatable : 해당 컬럼 등록 / 변경 가능 여부 지정
- nullable : null 값의 허용 여부를 설정한다. (DDL 생성 시 not null 제약조건이 붙는다)
- unique : @Table의 uniqueConstraints와 같으며 한 컬럼에 유니크 제약 조건을 걸 수 있다.
- @Table로 유니크 제약조건을 거는 것을 권장
- @Column으로 유니크 제약조건을 걸면 제약조건 명을 따로 지정할 수 없고 랜덤으로 나온다.
- columnDefinition : 데이터베이스 컬럼 정보를 직접 줄 수 있다.
- ex) columnDefinition = "varchar(100) default 'EMPTY'")
- length : 문자 길이 제약 조건 (String 타입에만 사용한다)
- precision, scale : BigDecimal 타입에서 사용 (아주 큰 숫자 타입)
기본 키 매핑
- 기본 키 직접 할당 - @Id만 사용
- 기본 키 자동 생성 - @GeneratedValue 사용
- IDENTITY : 기본 키 생성을 데이터베이스에 위임
- 주로 MYSQL(AUTO_INCREMENT), Postgre SQL에서 사용
- 영속성 컨텍스트에서 관리되려면 pk 값이 존재해야하는데 DB에 저장되는 시점에 id 값을 알 수 있다.
그렇기에 IDENTITY는 제약이 존재한다. - IDENTITY 전략 제약 - 보통 JPA는 commit 시점에 DB로 쿼리를 flush 하지만 IDENTITY 전략의 경우 persist()를 호출한 시점에 쿼리를 flush를 한다. DB에 쿼리를 flush하는 시점에 id 값을 알 수 있다.
- SEQUENCE: 데이터베이스 시퀀스 오브젝트 사용
- 주로 ORACLE에서 사용
- 테이블마다 시퀀스를 따로 사용하고 싶은 경우 @SequenceGenerator 필요
- persist() 호출 시점에 데이터베이스 시퀀스에서 값을 가져와서 영속성 컨텍스트에 저장하고 commit 시점에 flush 한다.
- persist()를 호출할 때마다 시퀀스 값을 네트워크를 통해 가져와야하므로 성능 문제가 생길 수 있다.
- 최적화를 위한 옵션 - allocationSize 옵션을 통해 값을 지정하면 지정한 값이 될 때마다 네트워크를 통해 시퀀스 값을 가져온다.
- ex) allocationSize가 50이면 id 값이 1씩 증가하여 50이 될 때까지 시퀀스 값을 네트워크를 통해서 가져올 필요가 없다.
- TABLE : 키 생성용 테이블을 만들어서 데이터베이스 시퀀스를 흉내내는 전략
- 모든 DB에서 사용 가능
- @TableGenerator로 별도의 키 생성용 테이블을 생성하고 내부 컬럼에 지정한 키 이름과 값을 사용한다.
- SEQUENCE 전략과 마찬가지로 최적화를 위해 allocationSize 옵션이 있다.
- AUTO : 방언에 따라 자동 지정
- IDENTITY : 기본 키 생성을 데이터베이스에 위임
- 권장하는 식별자 전략
- 기본 키 제약 조건 -> 미래까지 조건을 만족하는 자연키는 찾기 어렵기에 대리키(대체키)를 사용하자.
- null이 아니다
- 유일하다
- 변하면 안된다
- 권장하는 방법 : Long 타입(큰 범위 + 기본 값이 null) + 대체키 + 키 생성전략 사용
- 기본 키 제약 조건 -> 미래까지 조건을 만족하는 자연키는 찾기 어렵기에 대리키(대체키)를 사용하자.
- 자연키 : 비지니스적으로 의미있는 키를 의미한다.
- ex) 주민등록번호, 전화번호 ....등등
- 대체키 : 비지니스적으로 전혀 상관이 없는 키를 의미한다.
- ex) 랜덤 값
- 테이블과 매핑 시 제약 조건들을 소스코드에 적어주면 개발자 입장에서 보기 편해진다.
- ex) length, index .... 등등
- 자바 변수명(카멜 케이스) 관례와 DB 컬럼명(대문자_대문자, 소문자_소문자) 관례가 서로 다르기에 @Column(name = "컬럼명")으로 지정해주는 경우도 있다.
- 스프링 부트를 사용하면 자바의 카멜 케이스를 자동으로 소문자_소문자로 변환해준다.
- 데이터 중심 설계의 문제점
- 객체 설계를 테이블 설계에 맞춘다.
- 테이블의 외래키를 객체에 그대로 가져온다.
- 객체 그래프 탐색이 불가능 = 참조를 할 수 없다.
- 객체 그래프 탐색 ex) member.getOrder.getProduct.~
출처: [인프런 김영한 자바 ORM 표준 JPA 프로그래밍 - 기본편]
https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
자바 ORM 표준 JPA 프로그래밍 - 기본편 강의 | 김영한 - 인프런
김영한 | JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., 실무에서도
www.inflearn.com
'Spring > [인프런 김영한 자바 ORM 표준 JPA 프로그래밍 - 기본편]' 카테고리의 다른 글
[인프런 김영한 자바 ORM 표준 JPA 프로그래밍 - 기본편] 다양한 연관관계 매핑 (0) | 2024.08.22 |
---|---|
[인프런 김영한 자바 ORM 표준 JPA 프로그래밍 - 기본편] 연관관계 매핑 기초 (0) | 2024.08.20 |
[인프런 김영한 자바 ORM 표준 JPA 프로그래밍 - 기본편] 영속성 관리 (1) | 2024.08.19 |
[인프런 김영한 자바 ORM 표준 JPA 프로그래밍 - 기본편] JPA 시작하기 (0) | 2024.08.19 |
[인프런 김영한 자바 ORM 표준 JPA 프로그래밍 - 기본편] JPA 소개 (0) | 2024.08.19 |