자바 ORM 표준 JPA 프로그래밍 1~4장 정리

wannabeking·2022년 8월 27일
0

JPA

목록 보기
1/7

ORM, JPA

  • ORM이란 객체지향 언어와 관계형 데이터베이스의 패러다임 불일치를 해결하고 서로 매핑시켜주는 것
  • Java 진영에는 JPA가 존재
  • JPA를 쓰지 않으면 개발자가 직접 모든 쿼리를 작성하며 객체 <-> 데이터베이스 간 매핑을 위한 DAO를 일일히 작성해야함
  • 로직이 변경되면 관련된 모든 DAO를 수정해야함
  • JPA는 이러한 일련의 과정들을 생략하여 생산성을 증가시켜줌
  • JPA는 영속성 컨텍스트를 사용하여 효율성을 높임 (SELECT 시 처음은 DB에서 조회, 그 다음은 영속성 컨텍스트에서 조회)


영속성

  • 하나의 EntityManagerFactory는 여러개의 EntityManager 가짐 (EntityManagerFactory 앱 전체에서 하나만 생성하여 공유)
  • EntityManager는 데이터소스를 유지하며 통신한다. 스레드간 공유하거나 재사용하면 안됨
  • 사용 끝난 EntityManager는 close()하고, 앱 종료 시 EntityManagerFactory도 close() 하자
  • EntityTransaction은 em.getTransaction()으로 생성하고 .begin(), .commit()을 사용하여 트랜잭션 관리
  • em.flush()로도 쿼리 저장소에 쌓인 쿼리를 날릴 수 있지만 잘 사용하지 않음
  • JPQL을 사용하면 그 전까지 쿼리 저장소에 쌓인 쿼리를 날리고 JPQL 쿼리 실행
  • 트랜잭션을 사용하면 예외 시 롤백하고 트랜잭션 종료 시 자동으로 EntityManager가 flush 되니 사용하자
  • Entity는 비영속, 영속, 준영속, 삭제의 생명 주기를 가짐
  • 저장하거나 조회해온 Entity는 영속성 컨텍스트에 저장됨 (영속 상태)
  • em.detach로 하나의 Entity를 준영속으로 변경하거나 em.clear로 영속성 컨텍스트를 초기화하거나 em.close로 영속성 컨텍스트를 닫아서 Entity를 준영속으로 변경할 수 있음
  • em.remove로 삭제할 수 있음
  • 영속성 컨텍스트 내부에 Map을 사용하고 key가 @Id로 매핑한 식별자임
  • 엔터티를 수정하면 flush 할때 스냅샷과 비교하여 변경되었으면 수정 쿼리가 DB에 날라감 (변경 감지)
  • 변경 감지로 엔터티 수정할때 날라가는 쿼리는 특정 컬럼만 수정하는 것이 아니라 전체 업데이트하는 쿼리가 날라감 (쿼리 재사용성, 특정 컬럼만 수정하려면 @DynamicUpdate 어노테이션 사용해야함, 컬럼 30개 이상일때나 고려)
  • 조회 시 1차 캐시(영속성 컨텍스트)에 있으면 바로 가져오고 없으면 DB에 조회 쿼리 날리고 영속성 컨텍스트에 저장
  • 영속성 컨텍스트에서 똑같이 조회한 두 Entity는 == 연산이 true (동일성)
  • em.persist()하면 쓰기 지연 쿼리 저장소에 차곡차곡 저장하고 트랜잭션 커밋하면 한꺼번에 보냄 (쓰기 지연)
  • flush란 한마디로 영속성 컨텍스트의 변경내용을 데이터베이스와 동기화하는 것
  • 준영속 상태의 엔터티는 식별자값을 가지고 있고 em.merge()로 다시 영속화 가능 (비영속 상태의 엔터티도 merge()로 영속화 가능, save or update)


Entity

  • @Entity : 이 클래스를 테이블과 매핑한다고 알려주는 어노테이션, name 속성으로 엔터티명 설정 가능
  • @Table : name 속성을 사용하여 매핑하는 테이블의 이름 변경 가능, default는 엔터티명
  • @Id : 식별자(PK)에 달아주는 어노테이션 (식별자 반드시 필요)
  • @Column : 필드에 달아주는 어노테이션 (객체 필드 <-> DB 컬럼), name, nullable, unique(2개 이상이면 @Table의 uniqueConstraints 속성 사용), length(String <-> VARCHAR)
  • hibernate.hbm2ddl.auto 속성 : create, create-drop, update, validate(테이블과 엔터티 매핑이 다르면 앱 실행 X), none
  • 식별자 전략 -> IDENTITY, SEQUENCE, TABLE, AUTO(데이터베이스에 맞게)
  • IDENTITY는 데이터베이스에 위임하는 것으로 insert하여 생성된 식별자를 가져오고 영속성 컨텍스트에 저장
  • SEQUENCE는 저장될 식별자 DB에서 조회 후 영속성 컨텍스트에 저장, 커밋할때 한꺼번에 insert
  • TABLE은 식별자 테이블을 따로 생성하여 사용하는 것으로 식별자 테이블을 위한 커넥션이 별도로 필요 -> 데드락 발생 가능
  • 식별자는 자연 키보다는 대리 키를 사용하자 (자연 키가 변경되지 않으리란 보장 없음)
  • @Enumerated로 enum 매핑 가능하고 ORDINAL과 STRING 존재하는데 ORDINAL은 enum의 순서를 저장하는 것 (enum 수정 시 문제 발생하니 STRING 사용 권장)
  • @Temporal은 날짜 타입 매핑할때 사용 TemporalType.DATE, TIME, TIMESTAMP
  • @Lob은 대량의 데이터저장할때 사용 String, char[] -> CLOB 으로, byte[] -> BLOB으로 매핑
  • @Transient는 DB에 매핑하지 않고 객체에 임시적으로 값을 저장하고 싶을때 사용


profile
내일은 개발왕 😎

0개의 댓글