엔티티 매핑

원종서·2022년 2월 11일
1

JPA

목록 보기
5/13

@Entity

테이블과 매핑할 클래스는 @Entity 애노테이션을 필수로 붙인다.
@Entity가 붙은 클래슨느 JPA 가 관리하는 것으로, 엔티티라 부른다.

속성
name : JPA에서 사용할 엔티티 이름 지정 : 기본값 클래스 이름을 사용한다.

주의사항
1. 엔티티 클래스는 기본 생성자는 필수다.
2. final 클래스, enum, interface, inner 클래스에는 사용할 수 없다.
3. 저장할 필드에 final 을 사용하면 안된다.

@Table

@Table은 엔티티와 매핑할 테이블을 지정함. 생략하면 엔티티 이름을 테이블 명으로 사용한다.

속성
name : 매핑할 테이블 이름 : 기본값으로 엔티티 이름
catalog : catalog 기능이 있는 데베에서 catalog 를 매핑한다.
scheam : scheam 기능이 있는 데베에서 scheam 를 매핑한다.
uniqueConstraints : DDL 생성 시 유니크 제약조건 만든다. 2개 이상의 복합 유니크 제약조건도 만들 수 잇다.

기본 키 매핑

데베 벤더마다 기본키를 생성하는 방법이 다르기 때문에 JPA 의 기본키 맵핑의 방법은 여러개 존재한다.

1. IDENTITY 전략

이 전략은 기본 키 생성을 데베에 위임하는 전략이다.
주로 MySql, PostgreSql, SQL Server , DB2 에서 사용한다.

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

을 사용하면

create table member (
	id int not null auto_increment primary key, 
    ...

의 쿼리를 데베에 날린다.

이 방법은 데베에 값을 저장하고 나서야 기본 키 값을 구할 수 있을 떄 사용한다.

참고로 아이텐티티전략은 데이터를 데베에 삽입한 후에 기본 키 값을 조회 할 수 잇다. 따라서 엔티티에 식별자 값을 할당하려면 JPA는 추가로 데베를 조회해야한다. 하지만 하이버네이트는 Statement.getGeneratedKeys() 메서드로 데베에 저장하면서 동시에 생성된 기본키를 얻어온다.

또한 이 방법은 em.persist()를 하는 동시에 데베에 쿼리를 날린다. 데베에 저장되어야지 기본값을 얻을 수 있다.
기본값이 있어야만 엔티티가 영속상태로 될 수 있다.

2. SEQUENCE 전략

유일한 값을 순서대로 생성하는 특별한 데베 오브젝트다.
오라클, PostgreSQl, DB2, H2 데베에서 사용된다.

create table board (
	id bigint not null primary key,
    data varchar(255)
);

create sequence board_seq start with 1 increment by 1;
@Entity
@SequenceGenerator(
	name ="BOARD_SEQ_GENERATOR",
    sequenceName ="BOARD_SEQ",
    initialValue =1 , allocationSize= 1)
public class Board {
	@Id
    @GeneratedValue(Strategy = GenerationType.SEQUENCE, generator = "BOARD_SEQ_GENERATOR")
    private Long id;

우선 사용할 데베 시퀀스를 매핑한다.
@SequenceGenerator를 사용해 name 속성에 정의된 값을 등록한다.
그리고 sequenceName속성의 이름으로 지정된 값이 있는데 JPA는 이 시퀀스 생성기를 실제 데베의 BOARD_SQL 시퀀스와 매핑한다.

시퀀스 전략은 em.persist() 를 호출할 때 먼저 데베 시퀀스를 사용해 식별자를 조회한다. 그리고 조회한 식별자를 엔티티에 할당한 후 엔티티를 영속성 컨텍스트에 저장한다. 이후 트랜잭션 커밋해서 플러시가 일어나면 엔티티를 데베에 저장한다.

@SequenceGenerator 의 속성
name
= 식별자 생성기 이름 , 필수
sequenceName
= 데베에 등록되어 있는 시퀀스 이름 , 기본값 :hibernate_sequence
initialValue
= DDL생성시에 시퀀스 DDL을 생성할 떄 처음 시작하는 수, 기본값 1
allcationSize
= 시퀀스 한번 호출에 증가하는 수 , 기본값 : 50
catalog, schema
= 데베 catalog, schema 이름

CREATE SEQUENCE [sequenceName]
START WITH [initialValue] increment by [allcationSize]

TABLE 전략

키 생성 전용 테이블을 하남 ㅏㄴ들고 이름과 값으로 사용할 컬럼을 만들어 데베 시퀀스를 흉내내는 전략,
모든 데베에 적용 가능

create table My_SEQ (
	seq_name varchar(255) not null,
    next_val bigint,
    primary key (seq_name)
``

```java
@Entity
@TableGenerator(
	name ="BOARD_SEQ_GENERATOR",
    table ="My_SEQ",
	pkColumnValue ="BAORD_SQL", allocationSize= 1 )
public class Board {
	@Id
    @GeneratedValue(Strategy = GenerationType.TABLE, generator = "BOARD_SEQ_GENERATOR")
    private Long id;

AUTO 전략

이것이 제일 간단하다, 최고이다.

필드와 컬럼 매핑 : 래퍼런스

@Column

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

속성
name ,
insertable
= 엔티티 저장 시 이 필드도 같이 저장한다, false로 설정하면 이 필드는 데베 저장하지 않는다 (읽기 전용) , 기본값은 true
updateable
= 엔티티 수정 시 이 필드도 같이 수정한다, false로 설정하면 이 필드는 데베 수정하지 않는다 (읽기 전용) , 기본값은 true
table
= 하나의 엔테테를 두개 이상의 테이블에 매핑할 때 사용한다, 기본값은 해당 클래스가 매핑된 클래스
nullable
= 널 값의 허용을 설정, 기본값은 true
unique
= 한 컬렘에 유니크 제약조건 걸 때 사용, 두 컬럼 이상 유니크 제약 조건 사용하려면 클래스 레벨에서 @Table.uniqueConstraints 를 사용해야함
columnDefinition
= 데베 컬럼 정보를 직접 줄 수 있다.
lenght
= 문자 길이 제약 조건 STring 타입에만 사용
precision, scale
= BigDecimal 타입에서 사용 . presicion은 소수점을 포함한 전체 자릿수를, scale은 소수 자릿수다. double, float 타입에는 적용 안됨. 아주 큰 숫자나 정밀한 소수를 다룰 때 사용

  • 참고로 기본값에 @컬럼 애노테이션을 생략하면 DDL 생성 시 not null 가 붙은다
int data1; 

data1 integer not null // sql

반면에 래퍼 클래스나, 기본형에 @컬럼을 붙이면

Integer data2;

 data2 integer // sql

@Column // (nullable 의 기본값 false)
int data3

data3 integer // sql

이다.

@Enumerated

자바의 enum 타입을 매핑할 때 사용된다.

속성
value
= EnumType.ORDINAL : enum 순서를 데베에 저장,
EnumType.STRING: enum 이름을 데베에 저장

@Temporal

날자 타입을 매핑할 때 사용

속성
value
= TemporalType.DATE : 날자, 데베 date 타입과 매핑 (2022-2-11),
TemporalType.TIME : 시간, 데베 time 타입과 매핑 (10:54:12),
TemporalType.TIMESTAMP : 날짜와 시간 , 데베 timestamp 타입과 매핑 (10:54:12), 기본값은 없구 필수로 지정해야함.

@Temporal(TemporalType.DATE)
Date date; // sql : date date


@Temporal(TemporalType.TIME)
Time time; // sql time time

@Temporal(TemporalType.TIMESTAMP)
Date timestamp; // sql timestamp timestamp

@Temporal을 생략하면 자바의 Date 와 비슷한 timestamp 로 정의된다. (데베 방언에 따라 달라질 수 있다)

@Lob

데베의 BLOB, CLOB 타입과 매핑한다.
따로 속성이 없고, 필드 타입 기준으로 매핑한다.
CLOB = String ,char[], java.sql.CLOB
BLOB = byte[] , java.sql.BLOB

@Lob
String lobString; // longString lontext

@Lob
byte[] lobByte // lobByte longblob

@Transient

이 필드는 매핑하지 않는다.

@Access

JPA가 엔티티 데이터에 접근 방식을 지정
1. 필드지정 AccessType.FIELD .
필드에 직접 접근한다.
private 여도 접근 가능한다.

  1. 프로퍼티 접근 AccessType.PROPERTY
    게터를 사용한다.

@Access를 설정하지 않으면 @Id의 위치를 기준으로 접근 방식이 설정된다.

@Entity
public class Member {
	@Id
    private Long id;
    
    private String firstName;
    private String lastName;
    
    @Access(AccessType.PROPERTY)m,nm,nm,bnm,jlhflm.,/,m./jkolcuijlk;'l;'hilfio
    public String getFullName(){
   		return fistName + lastName;
    }

위 방식처럼 필드 접근 방식과 프로퍼티 접근 방식을 함께 사용해도 된다.

0개의 댓글