📌 엔티티 매핑
- 객체와 테이블 매핑:
@Entity
,@Table
- 필드와 컬럼 매핑:
@Column
- 기본 키 매핑:
@Id
- 연관관계 매핑:
@ManyToOne
,@JoinColumn
@Entity
@Entity
가 붙은 클래스는 JPA가 관리하며 엔티티라고 한다.@Entity
를 꼭 붙여주어야 한다.@Entity
를 붙여 매핑할 수 없다.)@Entity
속성@Table
: 엔티티와 매핑할 테이블을 지정한다.
DDL
: Data Definition Language 데이터 정의어)✔️ persistence.xml에서 hibernate.hbm2ddl.auto
데이터베이스 방언 별로 달라짐
DDL 생성 기능은 DDL을 자동 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않음
요구사항 추가
- 일반회원, 관리자의 구분
- 회원 가입일과 수정일 추가
- 회원을 설명할 필드가 필요(필드길이 제한 X)
✔️ hibernate.hbm2ddl.auto
@Column
@Enumerated
: 자바 enum 타입을 매핑할 때 사용
@Enumerated(EnumType.ORDINAL)
경우// Member.java
@Enumerated(EnumType.ORDINAL)
private RoleType roleType;
// persistence.xml
<property name="hibernate.hbm2ddl.auto" value="update" />
여기서 GUEST 객체 추가
@Enumerated(EnumType.STRING)
를 사용하자 @Enumerated(EnumType.STRING)
private RoleType roleType;
@Temporal
: 날짜 타입(java.util.Date, java.util.Calendar)을 매핑할 때 사용
(참고: LocalDate, LocalDateTime을 사용할 때는 생략 가능(최신 하이버네이트 지원))
@Lob
: 데이터베이스 BLOB, CLOB 타입과 매핑
@Lob
에는 지정할 수 있는 속성이 없다.CLOB
: String, char[], java.sql.CLOBBLOB
: byte[], java.sql, BLOB@Transient
@Transient
private Integer temp;
📌 기본 키 매핑 애노테이션
@Id
@GeneratedValue
@Id @GeneratedValue(strategy = GenerationType.Auto) private Long id;
@Id
만 사용@GeneratedValue
애노테이션으로 사용)@SequenceGenerator
필요@TableGenerator
필요 @Id
private String id;
@Column(name = "name", nullable = false)
private String username;
public Member() {
}
일단 위와 같이 다시 간단하게 세팅하고
📌 특징
- 기본 키 생성을 데이터베이스에 위임
- 주로
MySQL
,PostgreSQL
,SQL Server
,DB2
에서 사용- JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL 실행
- AUTO_INCREMENT는 데이터베이스에 INSERT SQL을 실행한 이후에 ID 값을 알 수 있음
- IDENTITY 전략은 em.persist() 시점에 즉시 INSERT SQL 실행하고 DB에서 식별자 조회
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
📌 특징
- 데이터베이스 시퀸스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트
오라클
,PostgreSQL
,DB2
,H2
데이터베이스에서 사용
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
@SequenceGenerator(name = "member_seq_generator", sequenceName = "member_seq")
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_seq_generator")
private Long id;
(운영에서는 잘 안 씀)
📌 전략
- 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀸스를 흉내내는 전략(테이블 하나 만들어서 키를 계속 뽑음)
- 장점: 모든 데이터베이스에 적용 가능
- 단점: 성능이 좀 떨어짐
@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;
즉, AUTO
나 SEQUENCE
를 사용하자.
📌 IDENTITY 문제점
IDENTITY전략은 Id에 값을 내가 넣으면 안된다. null로 날아오면 DB가 세팅해주는 방식인데 이는 DB에 들어간 후에야 Id 값을 알 수 있다는 문제점이 있다.
그런데 영속성 컨텍스트에서 관리되려면 무조건 pk 값이 있어야 한다. 그런데 DB에 들어가봐야(INSERT query를 날려봐야) 안다? → 문제 발생
그래서 특수하게
persist()
한 시점에 INSERT query를 날린다는 특징이 있다.@Entity // 스프링이 뜰 때 "애는 jpa를 사용하는 애구나" 알 수 있음 public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
📌 SEQUENCE에서도...
@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;
⬇️ 실제 트랜젝션 커밋하는 시점에 INSERT QUERY 호출 (
모았다가? 한 번에 쿼리를 날리는 것이 가능한(?))
📌 SEQUENCE -
allocationSize = 50