-
[JPA] 엔티티 매핑DEV/JPA 2024. 3. 7. 23:19
* 정보전달의 목적이 아닌 개인 스터디 정리 글 입니다.
강의 : 인프런 <자바 ORM 표준 JPA 프로그래밍 기본편>
교육자 : 김영한
객체와 테이블 매핑 : @Entity, @Table
필드와 컬럼 매핑 : @Column
기본키 매핑 : @Id
연관관계매핑 : @ManyToOne, @JoinColumn@Entitiy
@Entity가 붙은 클래스는 JPA가 관리
* 기본 생성자 필수
* final , enum, interface, inner클래스 사용 X
* 저장할 필드에 final 사용 X
속성 : name
- JPA에서 사용할 엔티티 이름 지정
- 기본값은 클래스 이름을 그대로 사용
- 같은 클래스 이름이 없다면 가급적 기본값 사용@Table
@Table은 엔티티와 매핑할 테이블 지정
속성- name : 매핑할 테이블 이름 (엔티티이름을사용)
- catalog : 데이터베이스 catalog 매핑
- schema : 데이터베이스 schema 매핑
- uniqueConstraints (DDL) : DDL 생성 시 유니크 제약 조건
<데이터베이스 스키마 자동생성>
- DDL을 애플리케이션 실행 시점에 자동 생성
- 테이블 중심 → 객체중심
- 데이터베이스 방언을 활용해서 데이터베이스에 맞는 적절한 DDL 사용 (ex : varchar, varchar2 ...)
- 이렇게 생성된 DDL은 개발에서만 사용. 운영 절대 X
- 생성된 DDL은 운영서버에서는 사용하지 않거나, 적절히 다듬은 후 사용하는것을 권장
@ hibernate.hbm2ddl.auto 속성
- create : 기존 테이블 삭제 후 다시생성 (drop + create)
- create-drop : create와 같으나 종료시점에 테이블 drop
- update : 변경분만 반영 (운영DB에 사용하면안됨) (alter table .. 컬럼 삭제는안되고 추가만됨)
- validate : 엔티티와 테이블이 정상 매핑되었는지 확인
- none : 사용하지않음 (아니면 주석처리해도 상관 X) ,관례상 none이라고 쓰며 아무 문자열을 입력해도 상관없음..매핑되는 속성값이 없기 때문
@ 주의
* 운영에서는 절대 create , create-drop, update 사용하면안됨
- 개발 초기단계는 create or update
- 테스트서버는 update or validate
- 스테이징과 운영서버는 validate or none
→ 서버 재실행할때마다 기존 테이블이 drop되거나 alter명령시 데이터베이스가 락이 걸리기때문
@ DDL생성기능
ex) 제약조건 추가 : 회원 이름은 필수, 10자 초과 x
@Column(nullable = false, length = 10)
ex) 유니크 제약조건 추가
@Table(uniqueConstraints = {@UniqueConstraint( name = "NAME_AGE_UNIQUE",
columnNames = {"NAME", "AGE"} )})
- DDL 생성기능은 DDL을 자동생성할때만 사용되고 JPA실행 로직에는 영향을 주지않는다.
<필드와 컬럼 매핑>
* 매핑 어노테이션
@Column : 컬럼속성
- name : 필드와 매핑할 테이블의 컬럼이름, default : 객체 필드이름
- insertable, updateable : 등록, 변경 가능 여부, default : true
- nullable (ddl) : null 허용여부
- unique (ddl) : @Table의 uniqueConstraints와 같지만 한 컬럼에 간단히 유니크 제약조건을 걸때 사용
- columnDefinition (ddl) : 데이터베이스 컬럼정보를 직접줄수있음 . ex ) varchar(100) default 'EMPTY'
- length (ddl) : 문자길이 제약조건. string 타입에만 사용, default : 255
- precision, scale (ddl) : BigDecimal(BigInteger) 타입에서 사용한다. precision은 소수점을 포함한 전체 자릿수를, scale은 소수의 자릿수다. 참고로 double,float타입에는 적용되지않는다. 아주 큰 숫자나 정밀한 소수를 다뤄야할때만 사용한다.
@Temporal : 날짜타입
- 날짜타입 매핑시 사용
- LocalDate, LocalDateTime 타입 사용시 생략가능 (최신하이버네이트 지원)
- value :
TemporalType.DATE: 날짜, 데이터베이스 date 타입과 매핑
(예: 2013–10–11)
TemporalType.TIME: 시간, 데이터베이스 time 타입과 매핑
(예: 11:11:11)
TemporalType.TIMESTAMP: 날짜와 시간, 데이터베이 스
timestamp 타입과 매핑(예: 2013–10–11 11:11:11)
@Enumerated : enum 타입
- value :
EnumType.ORDINAL : 순서를 데이터베이스에 저장
EnumType.STRING : 이름을 데이터베이스에 저장
default : EnumType.ORDINAL
** 데이터가 꼬일수있으므로 ORDINAL은 사용하지말것
@Lob : blob, clob
- Lob에는 지정할수있는 속성이없다.
- 매핑 필드 타입이 문자이면 CLOB, 나머지는 BLOB
- CLOB :String, char[], java.sql.CLOB
- BLOB :byte[], java.sql.BLOB
@Transient : 특정 필드를 컬럼에 매핑하지않음 (매핑 무시)
- 필드 매핑 X
- 데이터베이스에 저장 X, 조회 X
- 주로 메모리상에서만 임시로 값을 보관하고싶을때 사용
<기본키 매핑>
- 직접할당 : @Id 만 사용
- 자동생성 : @GeneratedValue
* 속성
• IDENTITY: 데이터베이스에 위임
- 주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용 (예: MySQL의 AUTO_ INCREMENT)
- JPA는 보통 트랜잭션 커밋 시점에 insert , 하지만 auto_increment는 데이터베이스에 insert sql을 실행한 이후에 id값을 알수있음
→ 따라서 commit 전 persist()시점에 즉시 insert sql 실행하고 db에서 식별자 조회ex)
@Entity public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 생략 // }
• SEQUENCE: 데이터베이스 시퀀스 오브젝트 사용(예: ORACLE)
- @SequenceGenerator 필요ex)
@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; // 생략 // }
* 속성
- name : 식별자 생성기 이름
- sequenceName : 데이터베이스에 등록되어있는 시퀀스 이름
- initialValue : DDL 생성시에만 사용. 시퀀스 ddl 생성할때 초기값 지정
- allocationSize : 시퀀스 한번 호출에 증가하는 수 (성능최적화에 사용. 기본값:50)
- catalog, schema : 데이터베이스 catalog, schema명
- Oracle, PostgreSQL, DB2, H2
• TABLE: 키 생성용 테이블 사용, 모든 DB에서 사용
- @TableGenerator 필요
- 키 생성 전용 테이블을 하나 만들어서 시퀀스를 흉내내는 전략
- 성능이 좋지않음.
ex )create table MY_SEQUENCES ( sequence_name varchar(255) not null, next_val bigint, primary key ( sequence_name ));
@Entity @TableGenerator( name = "MEMBER_SEQ_GENERATOR", table = "MY_SEQUENCES", pkColumnValue = "MEMBER_SEQ", allocationSize = 1) public class Member { @Id @GeneratedValue(strategy = GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR") private Long id; // 생략 // }
*속성
- name : 식별자 생성기 이름
- table : 키 생성 테이블명
- pkColumnName : 시퀀스 컬럼명 (seq_name)
- valueColumnNa : 시퀀스 값 컬럼명 (next_val)
- pkColumnValue : 키로 사용할 값 이름
- initialValue : 초기값, 마지막으로 생성된 값이 기준
- allocationSize : 시퀀스 한번 호출에 증가하는 수
- catalog, schema : 데이터베이스 카탈로그, 스키마 이름
- uniqueConstraints : 유니크 제약 조건을 지정할수있다.
• AUTO: 방언에 따라 자동 지정, 기본값
* 권장하는 식별자 전략
- 기본키 제약조건 : null 아님, 유일, 변하면안됨
- 미래까지 이 조건을 만족하는 자연키는 찾기 어렵다. 대리키(대체키) 사용하자.
- 권장 : Long형 + 대체키(uuid) + 키 생성 전략 사용'DEV > JPA' 카테고리의 다른 글
[JPA] 다양한 연관 관계 매핑 ( N:1 / 1:N / 1:1 / N:M ) (1) 2024.04.04 [JPA] 연관관계 매핑 기초 (0) 2024.03.29 [JPA] 영속성 관리 (0) 2024.02.22 [JPA] 시작하기, 기본 설정 (0) 2024.02.14 [JPA] 등장 배경, 개념 정리 (2) 2024.02.11