SQL은 테이블이 하나만 변경되어도 수정되어야하는 부분이 많음
객체와 관계형 데이터베이스의 차이
상속
객체의 상속을 테이블로 구현하기 위해서는 각각의 테이블을 두고, 외래 키로 상속처럼 다룰 수는 있다.
데이터 삽입 시 부모 테이블과 자식 테이블 SQL을 따로 작성해야한다.
하나의 자식 객체를 조회하려면 항상 부모 테이블과 자식 테이블을 조인해야만 한다.
연관관계
객체는 참조를 사용
테이블은 외래 키를 사용
데이터 타입
데이터 식별 방법
엔티티 신뢰 문제
객체가 다른 객체의 참조를 통해 연관관계를 맺을 때, DB 에서 SQL 에 따라 해당 객체만 가져올 지, 조인해서 여러 객체를 가져올 지 알 수 없으므로 엔티티의 모든 값이 제대로 되어 있을 거라는 신뢰가 없어짐
따라서 하단의 코드를 살펴봐야만 사용할 수 있음
그렇다고 항상 모든 객체를 가져올 수도 없음
진정한 의미의 계층 분할이 불가능하다.
객체답게 모델링 할수록 매핑 작업만 늘어난다.
객체를 자바 컬렉션에 저장 하듯이 DB에 저장할 수는 없을까? - JPA
JPA
Java Persistence API
자바 ORM 기술 표준
애플리케이션과 JDBC 사이에서 동작
EJB -> 하이버네이트 -> JPA
JPA 는 표준 인터페이스, 구현체는 3가지, 그 중 하이버네이트를 대부분 사용
객체에 필드만 추가하면 SQL을 알아서 수정
저장, 조회 역시 persist, find 메서드를 사용하여 여러 번의 SQL 필요 없이 간단하게 사용가능
성능 최적화
1차 캐시와 동일성 보장
같은 트랜잭션 내에서는 같은 엔티티 반환 - 약간의 조회 성능 향상
IL이 Read Committed 이어도 애플리케이션에서 Repeeatable Read 보장
트랜잭션을 지원하는 쓰기 지연
트랜잭션 커밋 전 발생하는 INSERT SQL 을 모아둠
커밋 시, JDBC BATCH SQL 기능을 사용해 한번에 SQL을 전송함
커밋 시 UPDATE, DELETE SQL 을 실행하여 DB 로우 락 시간을 최소화
지연 로딩
객체가 실제 사용될 때 로딩
미리 연관 객체까지 조인하여 가져오는 즉시 로딩도 지원하므로 상황에 맞게 사용
ORM
Object-relational mapping
객체는 객체대로 설계
관계형 데이터베이스는 관계형 데이터베이스대로 설계
중간에서 ORM 프레임워크가 매핑
참고.
Read Committed : 커밋된 데이터만 읽어옴, 트랜잭션 수행 중 다른 트랜잭션의 커밋이 일어나면 변경사항을 반영한 데이터를 읽어옴
Repeatable Read : 트랜잭션 시작 전 커밋된 데이터만 읽어옴. 따라서, 트랜잭션 도중에 같은 위치의 데이터가 변경될 일이 없음