JPA 소개
SQL 중심적인 개발의 문제점
배경
- 지금 시대는 객체를 관계형 DB에 관리
- DB는 SQL만 알아들을 수 있기 때문에 SQL를 계속 작성 해야 함
문제점
- 무한 반복되고 지루한 CRUD 코드들
- 중간에 객체를 수정하면 해당하는 SQL 코드도 전부 수정 해야함
- 객체와 관계형 데이터베이스의 패러다임의 불일치
- DB의 목적 : 데이터를 잘 정규화해서 보관
- 객체의 목적 : 속성과 기능의 캡슐화
- 객체 지향 프로그래밍은 추상화, 캡슐화, 정보은닉, 상속, 다형성 등 시스템의 복잡성을 제어할 수 있는 다양한 장치들을 제공
- 객체를 관계형 DB에 저장하기 위해 SQL문을 작성해야 함
객체와 관계형 데이터베이스의 차이
상속

- 앨범 저장
- 객체 분해 -> Insert Item -> Insert Album
- 앨범 조회
- 각각의 테이블에 따른 조인 SQL
- 각각의 객체 생성
- 자바 컬렉션에 저장하면 list.add(album)
- 조회 : Album album = list.get(albumId)
- 부모 타입으로 조회 후 다형성 사용 가능
- Item item = list.get(albumId)
연관관계

- 객체는 참조 사용 : member.getTeam()
- 테이블은 외래 키 사용 : JOIN ON M.TEAM_ID = T.TEAM_ID
- 테이블에 맞춘 객체 저장

- 객체다운 모델링

- 객체는 자유롭게 객체 그래프를 탐색할 수 있어야 함

비교하기


결론
- 객체답게 모델링 할수록 매핑 작업이 늘어남
- 객체를 자바 컬렉션에 저장 하듯이 DB에 저장할 수 있는 방법이 필요
- JPA의 등장
JPA 소개
ORM
- Object-relational mapping(객체 관계 매핑)
- 객체는 객체대로 설계
- 관계형 DB는 관계형 DB대로 설계
- ORM 프레임워크가 중간에서 매핑
JPA
- JPA는 어플리케이션과 JDBC 사이에서 동작
소개

저장

조회

왜 JPA를 사용해야 하는가 ?
- SQL 중심적인 개발에서 객체 중심으로 개발
- 생산성, 유지보수
- 패러다임의 불일치 해결
- 성능 최적화
생산성, 유지보수
- 기본 CRUD 제공
- 저장(persist), 조회(find), 수정(member.setName()), 삭제(remove)
- 기존에는 필드 변경시 모든 SQL 수정
- JPA를 사용하면 필드만 추가하면 되고 SQL은 JPA가 처리
패러다임의 불일치 해결
- JPA와 상속


- 동일한 트랜잭션에서 조회환 엔티티는 같음을 보장
- 연관관계 저장, 객체 그래프 탐색을 보장
JPA의 성능 최적화
- 1차 캐시와 동일성 보장
- 같은 트랜잭션 안에서는 같은 엔티티를 반환 - 약간의 조회 성능 향상
- 트랜잭션을 지원하는 쓰기 지연
- 트랜잭션을 커밋할 때까지 INSERT SQL을 모음
- JDBC BATCH SQL 기능을 사용해서 한번에 SQL 전송
- 지연 로딩 : 객체가 실제 사용될 때 로딩
- 즉시 로딩 : JOIN SQL로 한번에 연관된 객체까지 미리 조회
데이터베이스 방언
- JPA는 특정 데이터베이스에 종속 X
- 각각의 데이터베이스가 제공하는 SQL 문법과 함수는 조씩 다름
- JPA는 해당 데이터베이스에 해당하는 SQL 문법과 함수를 자동으로 바꿔줌

JPA 시작
JPA 구동 방식
- 엔티티 매니저 팩토리는 하나만 생성해 어플리케이션 전체에서 공유
- 엔티티 매니저는 요청이 들어올 때마다 생성되며 쓰레드간에 공유하지 않는다 (사용하고 버림)
- 엔티티매니저는 Entity를 저장, 수정, 삭제, 조회하는 등의 엔티티와 관련된 모든 일을 처리한다.
- JPA의 모든 데이터 변경은 트랜잭션 안에서 실행

엔티티
- 엔티티 : 영속성을 가진 객체로 DB테이블에 보관할 대상
- @Entity 어노테이션 - 객체를 엔티티로 지정
- @Table 어노테이션 - 클래스 이름과 테이블 이름이 다를 때 테이블 이름을 지정
- @Id 어노테이션 - 엔티티를 식별하기 위한 식별자
엔티티매니저
find()
- 영속 컨테스트에서 엔티티를 검색하고 없으면 DB에서 데이터를 찾아 영속 컨텍스트에 저장
- 식별자는 @ID 어노테이션으로 지정한 값을 사용
persist()
- 엔티티를 영속 컨텍스트에 저장 후 INSERT 쿼리를 실행
- 보토 커밋시점에 쿼리를 실행하는데 바로 실행하는 경우도 있음
EntityManager entityManager = emf.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
try {
transaction.begin();
Hotel hotel = new Hotel("H101","서울호텔","STAR5");
entityManager.persist(hotel); transaction.commit();
} catch(Exception e) {
transaction.rollback(); ...
} finally {
entityManager.close();
}
remove()
- 엔티티 클래스를 영속 컨텍스트에서 삭제 후 DELETE 쿼리를 실행
엔티티 수정
- 별도의 upadate 메서드 존재 X
- JPA는 트랜잭션 범위에서 엔티티 객체의 상태가 변경되면 트랜잭션 커밋 시점에 반영
JPQL
- JPA는 SQL을 추성화한 JPQL이라는 객체 지향 쿼리 언어 제공
- SQL 문법과 유사
- JPQL은 엔티티 객체를 대상으로 쿼리
- SQL은 데이터베이스 테이블을 대상으로 쿼리
- 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
- SQL을 추상화하여 특정 데이터베이스 SQL에 의존 X