View
김영한님의 자바 ORM 표준 JPA 프로그래밍 강의를 들으며 공부한 내용을 정리한 글입니다.
객체와 테이블 매핑
JPA를 사용해 어떤 테이블과 매핑할 클래스는 @Entity 애너테이션을 필수적으로 명시해줘야 한다.
즉, @Entity가 붙은 클래스는 JPA가 관리하는 클래스라는 것을 나타낸다.
@Entity
public class Member {
.....
.....
}
Entity 클래스를 만들 때 몇 가지 주의할 점이 있는데, 주의 사항은 다음과 같다.
주의사항
- public 혹은 protected 레벨의 파라미터가 없는 기본 생성자는 필수이다.
- final 클래스, enum, interface, inner 클래스는 Entity로 사용할 수 없다.
- 값을 담는 필드에 final을 사용하면 안 된다.
@Entity의 속성
속성 | 기능 | 기본값 |
name | JPA에서 사용할 Entity의 이름 지정 | 클래스의 이름을 그대로 사용 |
@Table의 속성
속성 | 기능 | 기본값 |
name | 매핑할 테이블 이름 지정 | 엔티티 클래스 이름을 그대로 사용 |
catalog | 데이터베이스 catalog 매핑 | |
schema | 데이터베이스 catalog 매핑 | |
uniqueConstraints | DDL 생성 시에 유니크 제약 조건 생성 | |
indexes | 데이터베이스 index를 지정 |
데이터베이스 스키마 자동 생성
JPA를 활용해 데이터베이스와 매핑할 때, 스키마 생성에 대한 속성을 줄 수 있다.
이러한 속성은 일반적으로 application.properties 혹은 application.yml에 명시한다.
// application.yml
jpa:
hibernate:
ddl-auto: update
// application.properties
jpa.hibernate.ddl-auto: update
스키마 자동 생성 속성
속성 | 기능 |
create | 기존 테이블 삭제 후 다시 생성(drop + create) |
create-drop | create와 같지만 종료시점에 테이블을 drop 시킴 |
update | 변경된 부분만 반영 |
validate | 엔티티와 테이블이 정상 매핑되었는지 확인 |
none | 사용하지 않음 |
주의사항
- 운영 서버에는 절대 create, create-drop, update를 사용하면 안 된다.
- 스테이징과 운영 서버는 validate 또는 none 속성을 사용한다.
- 테스트 서버에서는 update 또는 validate 속성을 사용한다.
기본 키 매핑
객체와 테이블을 매핑했다면, 객체와 테이블의 기본 키에 대한 매핑이 필요하다.
기본 키 매핑에 사용되는 애너테이션은 다음과 같다.
- @Id
- @GeneratedValue
@Entity
public class Member {
@Id
@GenratedValue(strategy = GenerationType.AUTO)
private Long id;
}
@Id만 명시할 경우 Id 값을 직접 할당하겠다는 의미이며, 일반적으로는 @GeneratedValue(자동생성) 전략을 선택해 Id를 생성한다.
@GeneratedValue 전략
IDENTITY 전략
기본 키 생성을 데이터베이스에 위임한다.
MySQL의 AUTO_INCREMENT와 비슷한 기능이라고 생각하면 된다.
AUTO_INCREAMENT는 데이터베이스에 insert 쿼리가 실행된 후 ID 값을 알 수 있기 때문에
IDENTITY 전략은 persist() 시점, 영속화되는 시점에 insert 쿼리를 실행하고 식별자를 조회한다.
@Entity
public class Member {
@Id
@GenratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
SEQUENCE 전략
유일한 값을 순서대로 생성하는 데이터베이스 시퀀스 오브젝트를 사용한다.
데이터베이스에서 시퀀스 기능을 제공해야만 사용 가능한 DB 종속적인 전략이다.
@Entity
@SequenceGenerator(name = "MEMBER_SEQ_GENERATOR",
sequenceName = "MEMBER_SEQ" // 매핑할 데이터베이스 시퀀스 이름
initialValue = 1, allocationSize = 1)
public class Member {
@Id
@GenratedValue(strategy = GenerationType.SEQUENCE,
generator = "MEMBER_SEQ_GENBERATOR")
private Long id;
}
- @SequenceGenerator 속성
속성 기능 기본값 name 시퀀스 이름 지정 필수 값 sequenceName 데이터베이스에 등록되어 있는 시퀀스 이름 hibername_sequence initialValue 시퀀스 DDL을 생성할 때 처음 시작하는 수를 지정한다. DDL 생성 시에만 사용됨 1 allocationSize 시퀀스 한 번 호출에 증가하는 크기. 성능 최적화에 사용되며, DB 시퀀스 값이 하나씩 증가하도록 설정되어 있다면 반드시 1로 설정해야 한다. 50 catalog 데이터베이스 catalog 이름 schema 데이터베이스 schema 이름
TABLE 전략
키 생성 전용 테이블을 만들어서 데이터베이스 시퀀스 기능을 흉내 내는 전략이다.
시퀀스 기능을 제공하지 않는 데이터베이스에서도 적용 가능하지만 성능이 느리다는 단점이 있다.
// 키 생성 전용 테이블을 생성
CREATE TABLE MY_SEQUENCE {
sequence_name varchar(255) not null,
next_val bigint,
primary key ( sequence_name )
}
@Entity
@TableGenerator(name = "MEMBER_SEQ_GENERATOR",
table = "MY_SQUENCE"
pkColumnValue = "MEMBER_SEQ", allocationSize = 1)
public class Member {
@Id
@GenratedValue(strategy = GenerationType.TABLE,
generator = "MEMBER_SEQ_GENBERATOR")
private Long id;
}
- @TableGenerator 속성
속성 기능 기본값 name 식별자 생성기 이름 필수 값 table 키 생성 테이블 명 hibername_sequence pkColumnName 시퀀스 컬럼 명 sequence_name valueColumnNa 시퀀스 값 컬럼명 next_val pkColumnValue 키로 사용할 값 이름 엔티티 이름 initialValue 초기 값, 마지막으로 생성된 값이 기준 0 allocationSize 시퀀스 한 번 호출에 증가하는 크기. 성능 최적화에 사용되며, DB 시퀀스 값이 하나씩 증가하도록 설정되어 있다면 반드시 1로 설정해야 한다. 50 catalog 데이터베이스 catalog 이름 schema 데이터베이스 schema 이름 uniqueConstraints DDL 생성 시 유니크 제약 조건을 지정
AUTO 전략
@GeneratedValue의 기본 값으로 데이터베이스 별 방언에 따라 ID 값을 자동 지정한다.
@Entity
public class Member {
@Id
@GenratedValue(strategy = GenerationType.AUTO)
private Long id;
}
필드와 컬럼 매핑
이제 객체의 필드와 테이블의 컬럼을 매핑할 때 사용하는 매핑 애너테이션들과 그 속성을 알아보자.
먼저, 컬럼 매핑에 사용되는 애너테이션은 다음과 같다.
- @Column - 컬럼 매핑
- @Temporal - 날짜 타입 매핑
- @Enumerated - enum 타입 매핑
- @Lob - BLOB, CLOB 매핑
- @Transient - 특정 필드를 컬러에 매핑하지 않음(매핑 무시)
@Entity
public class Member {
@Id
private Long id;
@Column(name = "name")
private String username;
private Integer age;
@Enumerated(EnumType.STRING)
private RoleType roleType;
@Temporal(TemporalType.TIMESTAMP)
private Date createDate;
@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
@Lob
private String description;
}
@Column의 속성
@Column은 필드와 테이블 컬럼을 매핑할 때 사용한다.
DDL이 붙은 속성들은 DDL을 자동 생성할 때만 사용되고 JPA 실행 로직에는 영향을 주지 않는다.
@Column 애너테이션은 아래와 같은 속성들을 가지고 있다.
속성 | 기능 | 기본값 |
name | 필드와 매핑할 컬럼 명 | 객체 필드 이름 |
insertable | 등록 가능 여부 | true |
updatable | 변경 가능 여부 | true |
nullable(DDL) | null 허용 여부 | |
unique(DDL) | @Table의 uniqueConstraints와 같지만 하나의 컬럼에 간단히 유니크 조건을 걸 때 사용한다. | |
columnDefinition(DDL) | DB 컬럼 정보를 직접 줄수 있다. | |
length(DDL) | 문자 길이 제약 조건 | 256 |
precision | BIgDecimal 혹은 BigInteger 처럼 큰 숫자나 정밀한 소수를 다루어야 할 때 사용한다. 소숫점을 포함한 전체 자릿수를 나타냄 | 19 |
scale(DDL) | BIgDecimal 혹은 BigInteger 처럼 큰 숫자나 정밀한 소수를 다루어야 할 때 사용한다. 소수의 자릿수를 나타냄 | 2 |
@Enumerated 속성
@Enumerated는 enum 타입을 매핑할 때 사용한다.
속성 | 기능 | 기본값 |
value | EnumType.ORDINAL - enum 순서를 데이터 베이스에 저장 EnumType.STRING - enum 이름을 데이터 베이스에 저장 |
EnumType.ORDINAL |
@Enumerated를 사용한다면 EnumType.STRING
을 사용하자.
이를 생략하면 기본값인 EnumType.ORDINAL으로 속성이 설정된다.
ORDINAL은 Enum의 순서를 나타내는 Integer 값이 데이터베이스에 저장되기 때문에 깨지기 쉽다. 또한, 숫자로 저장되므로 어떤 값을 나타내는지 명확하지도 않다.
@Temporal 속성
@Temporal은 날짜 타입을 매핑할 때 사용한다.
속성 | 기능 | 기본값 |
value | TemporalType.DATE: 날짜, 데이터베이스 date 타입과 매핑 (예: 2013–10–11) TemporalType.TIME: 시간, 데이터베이스 time 타입과 매핑 (예: 11:11:11) TemporalType.TIMESTAMP: 날짜와 시간, 데이터베이스 timestamp 타입과 매핑 (예: 2013–10–11 11:11:11) |
@Lob 속성
@Lob은 BLOB, CLOB 타입을 매핑할 때 사용한다.
지정할 수 있는 속성이 없으며, 필드 타입이 문자면 CLOB을 나머지는 BLOB을 매핑한다.
- CLOB: String, char[], java.sql.CLOB
- BLOB: byte[], javs.sql.BLOB
@Transient 속성
필드 매핑을 하지 않을 때 명시하는 애너테이션이다.
주로 메모리상에 임시로 값을 보관하고 싶을 때 사용한다.
@Transient
private Integer something;
'BackEnd > JPA' 카테고리의 다른 글
JPA 영속성 컨텍스트 (0) | 2021.12.03 |
---|---|
[JPA] JPA 소개와 알아보기 (0) | 2021.10.11 |