[자바 ORM 표준 JPA 프로그래밍] - 4. 엔티티 매핑

쓰옹·2023년 5월 13일
0

JPA

목록 보기
4/4

김영한, ⌜자바 ORM 표준 JPA 프로그래밍⌟ 과
인프런 강의 <자바 ORM 표준 JPA 프로그래밍 - 기본편> 으로
공부한 JPA를 정리한 내용이다.

JPA를 사용하는 데 가장 중요한 일은 엔티티와 테이블을 정확히 매핑하는 것이다. (정적/설계적 측면)

대표 매핑 어노테이션

  • 객체와 테이블 매핑: @Entity @Table
  • 기본 키 매핑: @Id
  • 필드와 컬럼 매핑: @Colum

객체와 테이블 매핑

@Entity

JPA 사용으로 테이블과 매핑할 클래스는 필수로 붙여야 함.
JPA가 관리하는 클래스가 되게 해주지

적용 주의사항

  • 기본생성자 필수
  • final 클래스, enum, interface, inner 클래스 사용 불가
  • 저장할 필드에 final 사용 불가

속성

속성기능기본값
name엔티티 이름 지정.
다른 패키지에 같은 이름의 엔티티클래스가 있다면 이름을 지정해 충돌하지 않게 해야 함.
클래스이름 고대로

@Table

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

속성

속성기능기본값
name매핑할 테이블 이름엔티티 이름 사용
catalogcatalog기능이 있는 DB에서 catalog매핑
schemaschema기능이 있는 DB에서 schema매핑
uniqueConstraints
(DDL)
DDL 생성 시 유니크 제약조건 생성
스키마 자동 생성 기능을 사용해서 DDL을 만들 때만 사용됨

필드와 컬럼 매핑

@Column

객체 필드를 테이블 컬럼에 매핑

속성

속성기능기본값
name컬럼 이름 지정객체의 필드 이름
insertable/updatable
(거의 사용하지 않음)
엔티티 저장/수정 시 해당 필드도 같이 저장/수정
false -> 저장/수정 안함. 읽기 전용일 떄 사용
true
table
(거의 사용하지 않음)
하나의 엔티티를 두 개 이상의 테이블에 매핑할 때 사용현재 클래스가 매핑된 테이블
nullable
(DDL)
null값 허용 여부
false -> DDL 생성 시 not null 제약조건
true
unique
(DDL)
유니크제약조건. 키가 복잡한 이름으로 설정됨
@Table.uniqueConstraints(키 이름 설정 가능)와 같음
DDL) alter table Tablename add constraint UK_Xxx unique (username)
columnDefinition
(DDL)
직접 컬럼 정보 설정
ex) "varchar(100) default 'EMPTY'"
필드의 자바 타입과 방언 정보를 사용해 적절한 컬럼 타입 생성
length
(DDL)
문자길이 제약조건. String 타입에만 사용255
precision, scale
(DDL)
BigDecimal타입에서 아주 큰 숫자나 정밀한 소수를 다루어야 할 때만 사용precision=19, scale=2

생략한다면?

@Column 속성의 기본값 적용

  • 예외
    자바 기본타입(Primitive Type): null값 입력할 수 없음
    -> nullable 속성 예외

    • 예시코드
       // @Column 생략, 자바 기본타입
      int data1;
      data1 integer not null // 생성된 DDL
      
      // @Column 생략, 객체 타입
      Integer data2;
      data2 integer // 생성된 DDL
      // 객체타입일 때만 null값 허용
      
      // @Column 사용, 자바 기본 타입
      @Column
      int data3;
      data3 integer // 생성된 DDL
      // @Column 사용하면 기본값이 true이기 때문에 nullabe=false로 지정하는 것이 안전함

@Enumerated

enum 타입 매핑 시 사용

속성기능기본값
valueEnumType.ORDINAL: enum 순서를 DB에 저장
EnumType.String: enum 이름을 DB에 저장
EnumType.ORDINAL
  • 저장된 enum의 순서가 바뀌거나 추가되어도 안전하기 때문에 EnumType.String 권장

@Access

JPA가 엔티티 데이터에 접근하는 방식 지정

  • 필드 접근: AccessType.FIELD 필드에 직접 접근. 필드 접근 권한이 private이어도 접근 가능
  • 프로퍼티 접근: AccessType.PROPERTY 접근자 사용

설정하지 않으면 @Id 위치를 기준으로 접근방식 설정

기본키 매핑

  • 직접 할당: @Id
  • 자동 생성: @GeneratedValue 대리키 사용 방식
    @GeneratedValue(strategy=GenerationType.___
    • IDENTITY: 기본키 생성을 데이터베이스에 위임
    • SEQUENCE: 데이터베이스 시퀀스 사용해 기본키 할당
    • TABLE: 키 생성 테이블 사용

IDENTITY 전략

MySQL의 auto_increment기능

  • em.persist() 호출 즉시 INSERT SQL 데이터베이스에 전달
    • 엔티티가 영속상태가 되려면 식별자가 필요한데 데이터베이스에 저장을 해야 식별자를 구할 수 있기 때문
    • 트랜잭션을 지원하는 쓰기 지연이 동작하지 않음
  • 고렇지만 데이터베이스와 한 번만 통신함
    • JDBC3에 데이터를 저장하면서 동시에 생성된 기본 키 값도 얻어 오는 메서드 추가되었기 떄문이지!

SEQUENCE 전략

시퀀스: 유일한 값을 순서대로 생성하는 데이터베이스 오브젝트

시퀀스를 지원하는 데이터베이스에서 사용 가능 - 오라클, PostgreSQL, H2

시퀀스 매핑 코드

@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;

시퀀스 생성 DDL) create sequence member_seq{시퀀스이름} start with 1{이니셜밸류} increment by 1{얼로케이션사이즈}

...
	tx.begin();

	try {
		Member member = new Member();
		member.setName("sese");
		System.out.println("================");
		em.persist(member); // 호출 시 시퀀스 사용해 식별자 조회->엔티티할당 후 영속성 컨텍스트 저장
		System.out.println("member.id = "+member.getId());
		System.out.println("================");
		tx.commit(); // 플러시-> 인서트쿼리
	}
...

// 출력문
================
Hibernate: 
  call next value for member_seq
member.id = 1
================
Hibernate: 
  /* insert hello.jpa.Member
      */ insert 

...

@SequenceGenerator 속성

속성기능기본값
name식별자 생성기 이름필수
sequenceName디비등록되있는 시퀀스 이름hibernate_sequence
initialValueDDL 생성 시 처음 시작하는 수 지정1
allocationSize시퀀스 한 번 호출에 증가하는 수50

SEQUENCE 전략 최적화

시퀀스 전략은 시퀀스를 통해 식별자를 조회하는 추가 작업이 필요하기 때문에 데이터베이스와 2번 통신하게 됨. 인서트를 두 번 하면 시퀀스 접근도 두 번 해야됨 그래서 JPA가 시퀀스에 접근하는 횟수를 줄이기 위해 @SequenceGenerator.allocationSize을 사용함
기본값으로 설정하면 한 번에 시퀀스 값을 50 증가시키고 1~50까지는 메모리에서 식별자를 할당함 그리고 51이 되면 시퀀스 값을 100으로 증가시킴 이러면 동시성 문제가 없음

Table 전략

키 생성 전용 테이블을 만들고 이름과 값으로 사용할 컬럼을 만들어 더이터베이스 시퀀스를 흉내내는 전략으로 모든 데이터베이스에 적용할 수 있다는 장점이 있지만 성능면에서는 떨어지는 단점이 있음

식별자 선택 전략

데이터베이스 기본키 제약조건

  1. null값 허용하지 않음
  2. 유일
  3. 불변
    -> 먼 미래까지 불변 조건을 만족해야하는데 그런 자연키를 찾기가 어려움 so 대리키 사용

권장

Long형 + 대체키 + 키 생성전략 사용

데이터베이스 스키마 자동 생성

hibernate.hbm2ddl.auto 속성을 추가하면 실행 시점에 데이터베이스 테이블을 자동으로 설정함

  • 운영환경에서는 절대 사용하지 않아야..

    속성

    옵션설명
    create기존 테이블 삭제하고 새로 생성
    DROP + CREATE
    create-dropcreate+어플리케이션 종료 시 생성한 DDL 제거
    DROP + CREATE + DROP
    update데이블과 엔티티 매핑정보를 비교해 변경사항만 수정. only 추가, 삭제는 안됨
    validate테이블과 엔티티를 비교해서 차이가 있으면 경고를 남기고 어플리케이션 실행은 안함. DDL수정 안함
    none자동생성기능 사용 안함
profile
기록하자기록해!

0개의 댓글