JPA 기본 [1]

이름이름·2023년 1월 30일
0

Spring

목록 보기
12/20

엔티티매니저팩토리가 요청이 올대마다 엔티티매니저를 생성해서 줌
영속성 컨텍스트란 뭘까?
엔티티를 영구 저장하는 환경이라는 뜻
근데 DB에 저장한다는게 아니고 영속성 컨텍스트에 저장하는것임
persist 하면 영속상태
em.persist하면 비영속상태였던 객체가 엔티티 매니저 안에 들어가서 영속상태가 됨
app계층과 DB사이에 계층이 하나 더 있다고 보면됨

@Entity
클래스랑 테이블 매핑
name이라는 속성이 있긴한데 기본값으로 클래스이름임

@Table(name="MBR) 하면 DB의 MBR테이블에 매핑이됨

create : drop and create 기존테이블 삭제 후 새로 생성
create-drop : create와 같지만 종료시점에 drop
update : 변경분만 적용 (운영DB에는 사용X)
validate : 테이블과 매핑이 정상매핑 됐는지만 확인
none : 말 그대로 none

주의 할 점
운영 시 에는 절대 create, crerate-drop, update사용 X
스테이징과 운영 서버는 validate or none을 써야함

필드와 컬럼 매핑

객체에서는 username
DB테이블에서는 name으로 쓰고싶다면

@Column(name = "name)
private String username; 

이런식으로 쓰면 됨

Enum

Enum 타입은
@Enumerated(EnumType.String)
이런식으로 쓰면 됨

  • 무조건 EnumType은 String으로 해야함
    기본값이 Ordinary인데 절대 쓰면 안됨
    왜냐면 아래와 같이 순서를 저장하기 때문에 Enum에 새로운걸 추가하면 순서가 엉망이 되어버리기 때문
    • EnumType.ORDINAL: enum 순서를 데이터베이스에 저장
    • EnumType.STRING: enum 이름을 데이터베이스에 저장

@Temporal

날짜+시간은

@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;

-> 자바 Date에는 TIME, DATE, TIMESTAMP 세 가지가 있는데
TIMESTAMP가 TIME+DATE임
이 때 LocalDate , LocalDateTime 타입 사용이 가능하면 어노테이션 필요없음 어차피 타입만 보면 아니까 알아서 DB에 생성해줌

@LOB

BLOC, BLOC 매핑

기본키(Primary) 매핑

@Id @Generated 해주면 되는데
@Generated(Strategy.~) 에 속성이 좀 있음

  • Identity : MYSQL의 auto-increment
  • Sequence : ORACLE의 시퀀스오브젝트 이용
    데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트 (ORABLE, H2 등)
  • TABLE : 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉 내내는 전략
  • AUTO : 연결한 DB에 맞춰서 알아서 자동지정

단뱡향? 양방향?

  • 테이블
    테이블 입장에서는 방향이라는게 없다
    외래키 하나면 양쪽 조인이 가능
  • 객체
    객체 입장에서는
    한 쪽만 참조하면 단방향
    양 쪽 서로모두 참조하고 있으면 양방향

단방향 연관관계

원래의 방식은 한 테이블에서 다른 테이블로 참조할 때 참조하는 테이블의 pk를 가져오는 방식인데 이렇게 되면 참조하는 객체의 무언가를 얻고싶을때 그 pk를 가지고 참조하는 객체를 불러오고 불러온 객체에서 또 접근을 해야함

따라서 pk필드만 참조하는게 아니라 객체자체를 참조하도록 아래와 같이 타입을 객체(Team)로 해주고 어노테이션으로 관계를 지정해준다. 또 지금 이 Column이 참조하는 테이블의 어떤 Column를 참조하는지 @JoinColumn으로 정확하게 달아준다

@ ManyToOne
@ JoinColumn(name = "~~")
private Team team;

양방향 연관관계

양방향 보단 단방향이 좋고 되도록이면 단방향으로 하도록 하자
사실 생각해보면 양방향이 필요한 경우가 별로 없다
예를 들어 주문이랑 상품이 있다고 하면 주문입장에서는 상품의 pk가 중요하겠지만 상품입장에서는 주문이 중요할까?
근데 이제 JPQL이 복잡해지고 필요할 때가 있다 그럴때 양방향 하면됨

양쪽으로 서로 참조할 때 양방향 연관관계라고 함
DB에서 테이블의 경우는 FK만 있다면 서로 왔다갔다 할 수 있음
예를 들어 Team에 어떤 Member들이 있는지 궁금하다면 join을 해보면 됨
근데 객체의 경우에는 다름 아래와 같이 List members를 추가해줘야 왔다갔다 할 수 있음

사실 객체를 보면 단방향연관관계가 2개 있는거임
이 때 Member와 Test 중 하나만 연관관계의 주인으로 지정하고 그 주인만이 외래키를 관리해야한다. 이 때 외래키가 있는 쪽이 주인이 된다. 이렇게 되면 주인이 아닌 쪽은 읽기만 가능
(방법)주인이 아닌쪽은 @mappedBy 를 이용해 내가 누구한테 매핑당했는지를 명시해야한다
주의할 점: mappedBy가 있는 객체는 읽기전용이므로 뭔가 값 넣어놓고 왜 안되지 하지 않기

결론 : 일단 단방향으로만(only JoinColumn) 매핑하고 필요시에 양방향추가(mappedby)
단뱡향으로만 해도 연관관계 세팅은 이미 끝난거고 역으로 조회할 일이 많아지면 mappedby를 주인이 아닌쪽에 세팅해서 조회를 좀 더 편리하게 하는 것임

profile
공부 정리

0개의 댓글