@Entity
, @Table
@Column
@Id
@ManyToOne
@JoinColumn
@Entity
가 붙은 클래스는 JPA가 관리하며 엔티티라 한다.
JPA를 사용해서 테이블과 매핑할 클래스는 @Entity
를 꼭 붙여줘야 한다.
@Entity //JPA가 관리하는 객체
@Table(name="MBR") //어떤 테이블과 매핑할 지 이름 지정 가능
public class Member { ... }
<property name="hibernate.hbm2ddl.auto" value="create" />
persistence.xml에 위 속성값이 있다. create
일 경우 애플리케이션 로딩 시점에 drop table
하고 table들을 새로 만들어 낸다.
위와 같이 애플리케이션을 돌릴 때 drop table if exists로 테이블이 존재하면 삭제하고 create table로 새로운 테이블을 만드는 것을 확인할 수 있다.
옵션 값들은 다음과 같다
운영 장비에는 절대로 create, create-drop, update 사용 X
@Column(unique = true, length = 10)
private String name;
unique 여부, length와 같이 런타임에는 영향이 없지만 db에만 영향이 있는 경우
@Id
: PK 매핑
@Column(name="name")
: db의 컬럼명이 name
@Enumerated(EnumType.STRING)
: enum에 사용
@Temporal(TemporalType.TIMESTAMP)
: 날짜(Date 타입)에 사용
@Lob
: varchar를 넘는 큰 타입
@Transient
: db랑 매핑하고 싶지 않은 필드
name="name"
: 필드와 매핑할 테이블의 컬럼 이름 nullable : false
: not null 제약조건 unique : true
: unique 제약조건, 잘 쓰지 않음length = 10
: 길이 설정 columnDefinition=varchar(100) default EMPTY
: 컬럼의 설정을 직접 할 수 있다@Enumerated(EnumType.STRING)
으로 사용할 것 날짜 타입에 필요하다.
LocalDate
(년,월), LocalDateTime
(년,월,일)에는 생략 가능
매핑하는 필드 타입이 문자면 CLob, 아닐 경우 BLob
매핑 하기 싫을 때 사용
@Id
와 @GeneratedValue
사용
@Id
: Id를 직접 할당함 @GeneratedValue
: 자동생성인 경우 @GeneratedValue(strategy = GenerationType.AUTO)
db 방언에 맞춰 자동 생성된다
@GeneratedValue(strategy = GenerationType.IDENTITY)
기본 키 생성을 db에 위임 (MYSQL의 auto increment)
@GeneratedValue(strategy = GenerationType.SEQUENCE)
유일한 값을 순서대로 생성하는 특별한 db 오브젝트
@GeneratedValue(strategy = GenerationType.TABLE)
참고 : 필드 타입은 Long
을 사용하는게 좋다
@Table
: 키 생성 전용 테이블을 하나 만들어서 db 시퀀스를 흉내내는 전략 비즈니스와 상관 없는 대체 키를 사용하자
권장 : Long + 대체 키, + 키 생성전략
IDENTITY
전략은 DB에 데이터가 들어가야 값을 확인할 수 있음.
따라서 IDENTITY
전략일 경우에는 em.persist()
를 호출하는 순간 DB에 insert 쿼리를 날린다. 그리고 JPA 내부적으로 select 해서 영속성 컨텍스트로 가져오기 때문에 persist
이후 바로 id 값을 알 수 있다.
@Entity
@Table(name = "ORDERS")
public class Order {
@Id
@GeneratedValue
@Column(name="ORDER_ID")
private Long id;
@Column(name="MEMBER_ID")
private Long memberid;
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus status;
}
memberid
는 테이블의 외래 키를 그대로 가져와 객체 그래프로 바로 탐색할 수 없다.
Member
자체를 필드로 가지는게 객체지향스럽다