엔티티 매핑

OneTwoThree·2023년 7월 24일
0

출처


  • 객체와 테이블 매핑 : @Entity , @Table
  • 필드와 컬럼 매핑 : @Column
  • 기본 키 매핑 : @Id
  • 연관관계 매핑 : @ManyToOne @JoinColumn

객체와 테이블 매핑

@Entity가 붙은 클래스는 JPA가 관리하며 엔티티라 한다.
JPA를 사용해서 테이블과 매핑할 클래스는 @Entity를 꼭 붙여줘야 한다.

  • 기본 생성자는 꼭 있어야 한다
  • final 클래스, enum, interface, inner 클래스 X
  • 저장할 필드에 final 사용 X
@Entity //JPA가 관리하는 객체
@Table(name="MBR") //어떤 테이블과 매핑할 지 이름 지정 가능 
public class Member { ... }

DB 스키마 자동 생성

  • 애플리케이션이 뜰 때 테이블을 자동으로 만들도록 할 수 있다.
  • DB에 맞는 적절한 DDL 생성
  • 개발에서만 사용해야함
  • 운영서버에서는 사용하지 않고 적절하게 다듬어서 사용
<property name="hibernate.hbm2ddl.auto" value="create" />

persistence.xml에 위 속성값이 있다. create 일 경우 애플리케이션 로딩 시점에 drop table 하고 table들을 새로 만들어 낸다.

위와 같이 애플리케이션을 돌릴 때 drop table if exists로 테이블이 존재하면 삭제하고 create table로 새로운 테이블을 만드는 것을 확인할 수 있다.

옵션 값들은 다음과 같다

  • create : 기존 테이블 삭제 후 생성 drop , create
  • create-drop : create과 같은데 종료하는 시점에 테이블 drop
  • update : 변경분만 반영 (alter table), 지우는건 안됨
  • validae : 엔티티와 테이블이 정상 매핑 되었는지만 확인
  • none : 주석처리와 같음. 관례상 none이라고 씀

주의점

운영 장비에는 절대로 create, create-drop, update 사용 X

  • 개발 초기 단계 : create 또는 update
  • 테스트 서버 : update 또는 validate (create 할 시 다른 사람 데이터가 날라감)
  • 스테이징과 운영 서버 : validate 또는 none
    권장사항 : 로컬 pc에서만 자유롭게 하고 여러명이 쓰는 서버에서는 쓰지 않는다

DDL 생성 기능

    @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 타입)에 사용

  • TIMESTAMP : 날짜+시간
  • DATE : 날짜
  • TIME : 시간

@Lob : varchar를 넘는 큰 타입
@Transient : db랑 매핑하고 싶지 않은 필드


@Column

  • name="name" : 필드와 매핑할 테이블의 컬럼 이름
  • nullable : false : not null 제약조건
  • unique : true : unique 제약조건, 잘 쓰지 않음
  • length = 10 : 길이 설정
  • columnDefinition=varchar(100) default EMPTY : 컬럼의 설정을 직접 할 수 있다

@Enumerated

  • 무조건@Enumerated(EnumType.STRING) 으로 사용할 것
  • ORDINAL은 default 값이며 enum의 순서를 db에 저장하고 STRING은 enum의 이름을 저장한다.
  • ORDINAL 말고 STRING을 사용할 것

@Temporal

날짜 타입에 필요하다.
LocalDate(년,월), LocalDateTime(년,월,일)에는 생략 가능

@Lob

매핑하는 필드 타입이 문자면 CLob, 아닐 경우 BLob

@Transient

매핑 하기 싫을 때 사용

기본 키 매핑

@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 시퀀스를 흉내내는 전략
    • 장점 : 모든 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 자체를 필드로 가지는게 객체지향스럽다

0개의 댓글