본 문서는 인프런의 자바 ORM 표준 JPA 프로그래밍 - 기본편 (김영한) 강의를 공부하며 작성한 개인 노트입니다.
🌝 SQL 중심적인 개발의 문제점
애플리케이션은 객체지향, 데이터베이스는 관계형 > 객체를 관계형 DB에 관리
무한 반복, 지루한 코드
- CRUD, SQL를 자바 객체로, 자바 객체를 SQL로
- 복잡함. 유지보수 힘듬
패러다임의 불일치
객체형 vs. 관계형 데이터베이스
객체지향 프로그래밍 - 추상화, 캡슐화, 정보은닉, 상속, 다형성 등 시스템 복잡성 제어 장치 제공
- RDB, NoSQL, File, OODB 등에 저장
관계형 데이터베이스 > 현실적인 대안
- 객체를 관계형 데이터베이스에 저장: 객체 > SQL 변환 > SQL로 RDB에 저장
객체와 관계형 데이터베이스의 차이
- 상속

(예) 저장: 객체 분해 > INSERT INTO ITEM ... > INSERT INTO ALBUM
솔루션: 자바 컬렉션
list.add(album);
- 연관관계
- 객체 > 참조 (ex) member.getTeam()
- 테이블 > 외래 키 (ex) JOIN ON M.TEAM_ID = T.TEAM_ID
솔루션: 객체를 테이블에 맞추어 모델링
class Member {
String id;
Team team;
String username;
}
->
INSERT INTO MEMBER(MEMBER_ID, TEAM_ID, USERNAME) VALUES ...
솔루션: 객체 모델링, 자바 컬렉션에 관리
list.add(member);
Member member = list.get(memberId);
- 데이터 타입
객체 그래프 탐색: 객체는 자유롭게 객체 그래프를 탐색할 수 있어야 한다
- dot(.)을 이용해 관계를 탐색
- SQL은 처음 실행한 SQL에 따라 탐색 범위 결정
- 엔티티 신뢰 문제가 있음 > 데이터 타입이 뭔지 확신할 수 없음
- 모든 객체를 미리 로딩할 수 없음 > 상황에 따라 동일 메서드를 여러개 생성
- 실질적인 계층 분할이 어려움
- 데이터 식별 방법
SQL에서는 데이터가 같지만 instance가 다르게 생성
-> 자바 컬렉션에서 비교하면 같은 Instance로 인식
객체답게 모델링 -> 늘어나는 매핑 작업
🤸🏼♀️JPA 소개
Java Persistence API (JPA): 자바 진영의 ORM 기술 표준
public class example {
@PersistenceContext
EntityManager jpa;
public void save(Member member) {
jpa.persist(member);
}
public Member findOne(Long id) {
return jpa.find(Member.class, id);
}
}
ORM
Object-relational mapping: 객체 관계 매핑
- 객체는 객체대로, 관계형 디비는 관계형 디비로
- ORM 프레임워크가 중간에서 매핑
- 다른 언어에도 존재
JPA
- 애플리케이션과 JDBC 사이
- JPA가 개발자 대신에 JDBC API 씀
- JPA vs. JDBC:
- JPA는 객체를 저장할 때 알아서 분석해서 쿼리문 작성 & 요청하고 패러다임 불일치 해결
- 조회: 쿼리문 알아서 만들고 JDBC API 사용, 매핑, 패러다임 불일치 해결
JPA를 왜 사용해야 하는가?
SQL 중심 개발 > 객체 중심
생산성
- 저장:
jpa.persist(member)
- 조회:
Member member = jpa.find(memberId)
- 수정:
member.setName("")
- 삭제:
jpa.remove(member)
유지보수
- (기존) 필드 변경 > 모든 SQL 수정
- (JPA) 필드 변경 > 필드 추가
- 상속도 .add()으로 간단하게
- 자유로운 객체 그래프 탐색 (dot(.) 사용)
- 동일한 트랜잭션에서 조회한 엔티티는 같음을 보장
성능
- 1차 캐시와 동일성 보장
- 같은 트랜잭션 안에서 같은 엔티티 반환 > 조회 성능 향상
- DB isolation level이 read commit이여도 앱에서는 repeatable read
- 트랜잭션을 지원하는 쓰기 지연, transactional write-behind
- 커밋 때까지 트랜잭션을 모았다가 JDBC BATCH SQL로 한번에 전송
- 지연 로딩, lazy loading: 객체가 실제 사용될 때 로딩
- 즉시 로딩: 한번에 연관된 객체까지 미리 조회