그러나 슈퍼타입 - 서브타입 관계를 사용하더라도 객체의 저장 시 SQL문을 두 개를 사용해야 함
데이터를 조회해서 객체에 저장하려고 하면 JOIN문을 직접 작성해서 객체를 생성해야 함
만약 자바 컬렉션에 데이터를 저장한다면 타입 고민 없이 그냥 컬렉션을 사용하면 됨
연관관계
객체는 참조를 사용하고 테이블은 외래 키를 사용
객체는 참조 방향으로만 조회가 가능(단방향)
테이블은 외래 키 하나로 양방향 조회가 가능(MEMEBER JOIN TEAM / TEAM JOIN MEMBER)
객체를 테이블에 맞춰서 모델링 할 경우 객체지향의 장점을 이용할 수 없음
객체의 저장 / 조회는 편리함
객체 참조를 활용 불가능
객체지향적으로 모델링 할 경우 객체의 조회가 어려움
JOIN문을 사용해 연관된 필드를 조회하고 이를 매핑해주는 과정이 필요
객체 그래프 탐색이 어려움
객체 그래프 탐색: 객체에서 참조를 사용해서 연관관계를 탐색
SQL을 직접 다루면 처음 실행하는 SQL에 따라 객체 그래프를 어디까지 탐색할 수 있는지 정해짐
따라서 SQL문을 직접 보기 전 까지는 객체 그래프 탐색을 신뢰할 수 없음
class MemberService {
...
public void process() {
Member member = memberDAO.find(memberId);
member.getTeam(); // member -> team 객체 그래프 탐색이 가능?
member.getOrder().getDelivery(); // ???
}
}
그렇다고 매번 모든 연관관계를 전부 로딩하기에는 비용이 많이 듦
결국 상황에 따라 같은 객체에 대한 조회 쿼리를 여러 개 작성해야 함
동일성 비교의 문제
같은 SQL문을 사용해서 같은 트랜잭션에서 같은 객체를 조회하더라도 동일성 비교에는 실패함
데이터 타입
데이터 식별 방법
JPA 소개
JPA란?
Java Persistence API는 자바 진영의 ORM 표준 기술
ORM(Object-Relational Mapping)은 객체 - 관계형 데이터베이스 간 매핑을 해주는 프레임워크
JPA는 애플리케이션과 JDBC 사이에서 동작
SQL을 직접 작성할 필요 없이 JPA를 통해 객체를 직접 CRUD 할 수 있음
JPA가 적절한 SQL을 생성해줌
패러다임의 불일치 해결
JPA는 자바 ORM 기술에 대한 API 표준 명세
쉽게 말하면 인터페이스의 모음
JPA를 사용하려면 JPA의 구현체 프레임워크(ex 하이버네이트)를 사용해야 함
JPA를 사용해야 하는 이유
생산성
자바 컬렉션에 객체를 저장하듯이 사용 가능
SQL문을 작성하고 JDBC API를 사용하는 지루하고 반복적인 일을 JPA가 대신함
특히 데이터 수정 시 setter 하나만으로 처리 가능
유지보수
기존에는 필드 변경시 관련된 모든 SQL을 수정해야 했음
JPA 사용 시 필드만 추가하면 됨
패러다임의 불일치 해결
앞서 살펴본 패러다임의 불일치 문제를 해결해줌
자바 컬렉션을 사용하듯이 데이터베이스를 사용할 수 있음
성능
애플리케이션과 데이터베이스 사이에 계층이 하나 더 있으므로 최적화가 가능
캐싱, 지연 로딩 / 즉시 로딩 …
섹션 2.
섹션 3. 영속성 관리
영속성 컨텍스트
엔티티 매니저
엔티티를 저장하고, 수정하고, 삭제하고, 조회하는 등 엔티티와 관련된 모든 일을 처리(엔티티 관리자)
여러 스레드가 동시에 접근하면 동시성 문제 발생
데이터베이스 연결이 꼭 필요한 시점까지 커넥션을 얻지 않고 트랜잭션을 시작할 때 커넥션을 획득
엔티티 매니저 팩토리
엔티티 매니저를 만드는 공장
만드는 비용이 크므로 보통 한 개만 만들어서 애플리케이션 전체에서 공유
엔티티 매니저를 만드는 비용은 거의 들지 않음
여러 스레드가 동시에 접근해도 안전
영속성 컨텍스트(persistence context)
엔티티를 영구 저장하는 환경
영속성이란?
영속성(persistence)은 데이터를 생성한 프로그램의 실행이 종료되더라도 사라지지 않는 데이터의 특성을 의미한다.
엔티티 매니저를 통해 영속성 컨텍스트에 접근하고 영속성 컨텍스트를 관리 가능
엔티티의 생명 주기
비영속(new/transient): 영속성 컨텍스트와 전혀 관계가 없는 상태
엔티티 객체를 생성한 뒤 저장하지 않은 순수한 객체 상태
영속(managed): 영속성 컨텍스트에 저장된 상태
엔티티 매니저를 통해 엔티티를 영속성 컨텍스트에 저장 → 영속성 컨텍트스가 관리하는 상태
조회 메서드를 사용해 조회한 엔티티도 영속 상태
준영속(detached): 영속성 컨텍스트에 저장되었다가 분리된 상태
영속 상태의 엔티티를 영속성 컨텍스트가 관리하지 않는 상태
em.detach를 호출하면 준영속 상태
em.close를 호출해서 영속성 컨텍스트를 닫거나 em.clear를 호출해서 영속성 컨텍스트를 초기화해도 해당 영속성 컨텍스트가 관리하던 엔티티는 준영속 상태가 됨.
섹션 1. JPA 소개
SQL 중심적인 개발의 문제점
SQL 의존적인 개발을 피하기 어렵다.
패러다임의 불일치
객체와 관계형 데이터베이스의 차이가 많아 패러다임의 불일치로 오는 비용이 많음.
연관관계
객체 그래프 탐색이 어려움
JPA 소개
JPA란?
JPA는 자바 ORM 기술에 대한 API 표준 명세
JPA를 사용해야 하는 이유
setter
하나만으로 처리 가능섹션 2.
섹션 3. 영속성 관리
영속성 컨텍스트
엔티티 매니저
엔티티 매니저 팩토리
영속성 컨텍스트(persistence context)
엔티티의 생명 주기
em.detach
를 호출하면 준영속 상태em.close
를 호출해서 영속성 컨텍스트를 닫거나em.clear
를 호출해서 영속성 컨텍스트를 초기화해도 해당 영속성 컨텍스트가 관리하던 엔티티는 준영속 상태가 됨.em.remove
를 통해 삭제영속성 컨텍스트의 특징
엔티티 조회
영속성 조회
@Id
로 매핑한 식별자를 key로, 엔티티 인스턴스를 value로 가지는 Map이 존재em.find
메서드로 조회em.find
는 반복 호출해도 1차 캐시에 있는 같은 엔티티 인스턴스 반환true
(엔티티의 동일성 보장)엔티티 등록
em.persist
로 등록INSERT SQL
를 모아둠엔티티 수정
em.update
메서드는 존재하지 않음엔티티 삭제
em.remove
로 삭제em.find
로 삭제하려는 엔티티를 조회해야 함플러시
em.flush
직접 호출find
메서드는 플러시 실행하지 않음FlushModeType.AUTO
: 커밋이나 쿼리를 실행 시 플러시(기본값)FlushModeType.COMMIT
: 커밋할 때만 플러시준영속
준영속 상태
em.detach
em.clear
em.close
준영속 상태의 특징
em.merge