[JPA] 섹션 4 : 엔티티 매핑

헌치·2022년 7월 11일
0

JPA

목록 보기
3/4

노션 링크

4-1 객체와 테이블 매핑


객체와 테이블을 매핑한다

1) @Entity

JPA를 통해 테이블과 매핑할 클래스는 @Entity가 필수

  • 기본 생성자 필수
    • 생성자를 따로 만드므로 기본생성자를 따로 만들어줘야 함
  • finalenuminterfaceinner class 사용불가
  • 필드에 final 금지(바뀔 값 이니까)
  • name 속성 : JPA에서 쓸 엔티티 이름 지정(기본값 클래스 이름을 되도록 쓰자)

2) @Table

엔티티와 매핑할 테이블 지정

name 속성 : 매핑할 이름 지정(기본값 엔티티 이름)

  • 유니크 제약조건 추가
    @Table(uniqueConstraints = {
    		@UniqueConstraint( 
    			name = "NAME_AGE_UNIQUE", 
    			columnNames = {"NAME", "AGE"} 
    		)
    	}
    )

4-2 데이터베이스 스키마 자동 생성


DDL을 애플리케이션 실행 시점에 자동 생성

  • hibernate.hbm2ddl.auto=CREATE

1) DDL

  • DDL : Data definition language
    • DB를 정의하는 명령어
    • CREATEDROPALTERTRUNCATE 등

2) DDL 자동생성 기능

DB 중심 -> 객체 중심

  • 데이터베이스 방언을 활용
  • JPA 실행 로직에 영향 X
  • 개발 장비에서만 사용
    • 운영서버에서 사용하지 말자!(validatenone 사용)

3) 속성

  • create : 기존테이블 삭제 후 재생성(기존 테스트코드에서 쓰던 방식, DROP + CREATE)
  • create-drop : 종료 시점에 테이블 drop (DROP + CREATE + DROP)
  • update : 변경된 부분만 반영(운영 DB 사용 X : 테이블에 락 걸림)
  • validate : 엔티티와 테이블의 정상 매핑여부만 확인(DDL 수정 X)
  • none : 사용안함

4) 주의사항

운영장비에서는 createupdate 쓰지마라!!!

  • 개발 초기에는 create/update
  • 테스트 서버에서는 update/validate(여기서도 가급적 쓰지 마라)
  • 운영서버는 validate/none

4-3 필드와 컬럼 매핑


import java.beans.Transient;

@Entity
public class Member {
    @Id
    private Long id;    

		@Column(name = "name") // 해당 이름으로 칼럼 매핑    
		private String username;    
		private Integer age; // 생각한대로 매핑됨    

		@Enumerated(EnumType.STRING) // enum 타입 지정    
		private RoleType roleType;    

		@Temporal(TemporalType.TIMESTAMP) //날짜 매핑(TIMESTAMP : 날짜+시간)    
		private Date createdDate;    

		@Lob // 큰 컨텐츠(BLOB, CLOB 등)    
		private String description;    

		@Transient // 매핑에 사용 X    
		private int temp;
}

1) @Id

기본 키(PK)를 매핑한다

2) @Column

필드와 컬럼을 매핑한다

설정

  • name : 필드와 매핑할 테이블의 컬럼 이름
    • 자바 카멜표기법DB 언더스코어
      //해당 속성 추가를 통해 자동 변환 가능
      <property name="hibernate.ejb.naming_strategy"                   value="org.hibernate.cfg.ImprovedNamingStrategy" />
  • insertable : 등록가능 여부 지정
  • updatable : 변경가능 여부 지정
  • nullable : null 값 허용 여부 설정
  • unique : 유니크 제약조건 걸 때 사용(잘 안씀) -> @Table에서 검
  • columnDefinition : DB 칼럼정보를 직접 줌
  • length : 문자 길이 제약조건
  • precisionscale : BigDecimal(큰 숫자, 소수점 등) 타입에서 사용

제약조건 추가

@Column(nullable = false, length = 10)

3)@Enumerated

enum 이름을 DB에 저장

EnumType.STRING을 사용하자!

(EnumType.ORDINAL 사용 X)

4) @Temporal

날짜 타입(DateCalendar 유틸) 매핑

LocalDateLocalDateTime을 사용할 때는 생략 가능

5) @Lob

DB BLOB(문자X), CLOB(문자) 타입과 매핑

6) @Transient

해당 필드는 매핑X

7) @ManyToOne@JoinColumn

연관관계를 매핑 한다

  • 1대1m대n 등

8) @Access

JPA엔티티에 접근하는 방식을 지정

4-4 기본키(PK) 매핑


1) @Id

직접 할당

2) @GeneratedValue

자동 생성

  • AUTO : DB 방언에 따라 자동 지정(기본값)
  • IDENTITY : DB에 위임, MYSQL
  • SEQUENCE : DB 시퀀스 오브젝트 사용, ORACLE
  • TABLE : 키 생성용 테이블 사용, 모든 DB에서 사용, 성능저하 우려 있고 잘 안쓴다

3) IDENTITY 전략

기본 키 생성을 데이터베이스에 위임

class Member {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer id;
}

MySQL의 AUTO_INCREMENT 등에서 사용

AUTO_ INCREMENT

  • DB에 INSERT SQL을 실행한 이후에 ID 값을 알 수 있음
  • SELECT 문 없이, ID 값이 객체에 자동 매핑

방식

  1. DB에 엔티티 바로 저장
  2. 저장된 엔티티의 식별자(id) 값을 DB에서 조회
  3. 조회된 id를 엔티티에 매핑

4) SEQUENCE 전략

class Member {
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @SequenceGenerator(
            name = "MEMBER_SEQ_GENERATOR",
            sequenceName = "MEMBER_SEQ", // 매핑할 데이터베이스 시퀀스 이름            
						initialValue = 1, 
						allocationSize = 50
		)
    public Integer id;
}

allocationSize : 한번에 50개(기본값)의 인덱스 가져옴(테이블 전략에서도 사용되는 방식)

  • 동시성 이슈 해결
  • 대신 시퀸스 값이 한번에 많이 증가…

방식

  1. DB 시퀸스를 통해 id 조회
  2. 조회한 id엔티티에 할당
  3. 엔티티영속성 컨텍스트에 저장
  4. 트랜잭션 커밋 후, 엔티티DB에 저장

5) TABLE 전략

방식

  1. 키 생성 전용 테이블을 하나 만든다
  2. 여기에 이름으로 사용할 컬럼을 만든다
  3. 데이터베이스 시퀀스처럼 사용한다

6) 권장하는 식별자 전략

Long 형태

대체키 사용

IDENTITY 키 생성 전략(auto-increment)

PK 제약조건 : null 아님, 유일, 불변

  • 자연키를 찾기 힘들다
  • 대리키(대체키)를 쓰자
  • ex) 주민등록번호도 부적절

참고자료

  • [책, 강의] 자바 ORM 표준 JPA 프로그래밍(김영한)
profile
🌱 함께 자라는 중입니다 🚀 rerub0831@gmail.com

0개의 댓글