사용
- 실시간 데이터 처리에 적합
- 통계, 분석과 같은 쿼리에는 부적합 - myBatis 같은 실제 쿼리를 사용하는 것으로 해야 함
사용 이유
- SQL 에 의존적인 개발을 피하기 위함
- JPA 를 사용하지 않는 경우, 테이블이 변경되면 쿼리문 자체를 변경해줘야 함
- 테이블에 매핑된 객체를 신뢰할 수 없음, 객체와 쿼리문 두 곳을 DB와 비교해줘야 함
- JAVA 문법과 비슷하게 DB를 관리할 수 있음
- 여러 값을 저장할 때, List 와 같은 컬렉션을 지원하여, List 에 담고 저장하면 됨
- 패러다임에 불일치
-
관계형 데이터베이스는 테이블에 외래키를 사용하여 다른 테이블과 연관관계를 맺지만, 객체지향 모델링에서는 외래키가 존재하지 않아, 연관된 객체의 ID 를 직접 사용해서 관계를 억지로 맺음
객체A.setFK(객체B.getID())
insert(객체A)
"select * from 객체A where 객체A.FK = 객체B.ID"
- 데이터베이스와 독립적
- 각 DB 마다 같은 기능이지만 사용하는 방법이 다른 경우가 많다. JPA 를 사용하지 않는 경우 처음 개발할 때 사용한 DB 에 맞춰서 기능을 구현하면 다른 DB를 사용 할 때 다시 수정해야 하는 경우가 발생한다.
- 예를 들어 페이징 처리
- 성능
- JPA 는 성능 최적화 기능을 제공한다.
- find() 로 조회하는 객체는 처음 조회시에만 DB를 조회하고, 그 이후에 수정사항이 없으면 이미 조회된 객체를 가져온다.
JPA(JAVA Persistence API)
- JAVA 진영의 ORM 기술에 대한 API 표준 명세, 쉽게 말해 인터페이스를 모아둔 것
- ORM (Object-Relational Mapping) 은 객체와 관계형 데이터베이스를 매핑한다는 뜻
- 객체와 테이블을 매핑해서 패러다임의 불일치를 개발자 대신 해결
- 값을 저장하는 경우, 객체를 자바 컬렉션에 저장하듯이 ORM 프레임워크에 저장한다.
- Entity 를 분석
- INSERT SQL 을 생성
- JDBC API 사용
- 패러다임 불일치 해결
엔티티 매니저
- 엔티티 매니저 팩토리 - 엔티티 매니저를 생성하는 클래스, 여러 스레드가 동시에 접근해도 안전하므로 서로 다른 스레드간에 공유 허용
- 현재 MustP 프로젝트에서는 기본 생성되는 엔티티매니저 팩토리 사용
- 엔티티 매니저는 여러 스레드가 동시에 접근 시, 동시성 문제가 발생하므로 스레드 간 공유하면 안됨
- DB 커넥션을 사용하는 주체로, DB 와 연결되는 객체
- 객체를 영속 컨텍스트에 저장하는 역할
영속성 컨텍스트
- 식별자 구분
- 영속성 컨텍스트는 엔티티를 식별자 값(@Id 로 매핑한 값) 으로 구분하여, 영속 상태는 식별자 값이 반드시 있어야 함
- 데이터베이스 저장
- 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 데이터베이스에 반영 (플러시)
- 장점
- 1차 캐시
- 영속 컨텍스트 내부에 캐시 데이터가 있어, 조회하려는 엔티티가 1차 캐시 내부에 존재하면 DB를 조회하지 않고, 캐시 데이터로 반환
- 동일성 보장
-
1차 캐시 내부에 데이터가 존재하는 경우, 아래 코드가 성립한다
-
동일한 메모리 주소에 있는 객체를 반환
객체 A = find("1");
객체 B = find("1");
if(A == B)
System.out.println("TRUE");
- 트랜잭션을 지원하는 쓰기 지연
- 변경 감지
- 영속 상태의 엔티티의 내부 값이 변경되는 경우, 데이터베이스에 자동으로 반영 하는 기능
- 단, 영속 상태의 엔티티에만 적용됨
- 지연 로딩
- 생명주기
- 비영속 (transient)
- 영속 (managed)
- 준영속 (detached)
- 삭제 (removed)
플러시
- 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영
- 직접 호출
- 트랜잭션 커밋 시 플러시 자동 호출
- JPQL 쿼리 실행 시 플러시 자동 호출
- find() 를 호출할 때는 호출되지 않음
- FlushModeType.AUTO : 커밋이나 쿼리를 실행할 때 플러시 ( 기본값 )
- FlushModeType.COMMIT : 커밋할 때만 플러시
spring.jpa.hibernate.ddl-auto ( DDL 자동 생성 )
- none : 실제 유효하지 않는 값으로, 자동 생성 기능을 사용하지 않을 때 많이 사용
- create : 기존 테이블 삭제 후 테이블 생성, DROP + CREATE
- create-drop : 기존 테이블 삭제 후 테이블 생성, 종료 시점에 테이블 삭제 DROP + CREATE + DROP
- update : 데이터베이스 테이블과 엔티티 매핑정보를 비교해서 변경 사항만 수정
- validate : 데이터베이스 테이블과 엔티티 매핑정보를 비교해서 변경 사항이 있으면 애플리케이션을 실행하지 않음, DDL 을 수정하지 않는다.
update 옵션에서 컬럼 삭제는 엄청난 문제를 발생시킬 수 있기 때문에 컬럼 추가만 반영된다. 개발 초기에는 create 또는 update 옵션을 이용해서 익숙해지는 데 집중하고 추후에 validate 옵션을 설정해주는 것이 좋다.
스테이징, 운영환경에서는 절대로 create, create-drop, update를 사용하면 안된다. 스테이징과 운영 서버에서는 테이블 생성 및 컬럼 추가, 삭제, 변경은 데이터베이스에서 직접하며, none을 사용하거나 validate를 이용해 정상적인 매핑 관계만 확인해야 한다.