티스토리 뷰
SQL 중심적인 개발의 문제점
- 무한 반복, 지루한 코드 (CRUD)
- SQL에 의존적인 개발을 피하기 어렵다
패러다임의 불일치
객체 지향(OOP) vs 관계형 데이터베이스(RDB)
개발자가 SQL 매퍼(Mapper)를 통해 객체를 RDB에 저장한다.
객체와 관계형 데이터베이스의 차이
1. 상속 - 객체는 상속을 지원하지만, RDB는 지원하지 않는다(유사한 것 있음)
2. 연관관계 - 객체는 참조를 사용하지만, RDB는 외래 키를 사용한다.
3. 데이터 타입
4. 데이터 식별 방법
객체 그래프 탐색 - 객체는 연관된 것끼리 자유롭게 객체 그래프를 탐색할 수 있어야 한다.
엔티티 신뢰 문제 - 계층형 아키텍처(Layered Architecture)에서 엔티티는 신뢰할 필요가 있다.
모든 객체를 미리 로딩할 수 없다 - 상황에 따라 동일한 조회 메서드를 여러번 생성한다.
객체답게 모델링 할수록 매핑 작업만 늘어난다.
JPA는 객체를 자바 컬렉션에 저장하듯이 DB에 저장하는 것을 지원한다.
JPA
- Java Persistence API
- 자바 ORM 기술 표준
ORM(Object-Relational Mapping)
- 객체-관계 매핑
- 객체는 객체대로 설계, RDB는 RDB대로 설계
- 객체와 RDB 중간에서 ORM 프레임워크가 중간에서 매핑
JPA 표준 명세
- JPA는 인터페이스의 모임
- Hiberante, EclipseLink, DataNucleus
JPA를 사용해야 하는 이유
- SQL 중심 개발 -> 객체 중심 개발
- 생산성, 유지보수
- 패러다임 불일치 해결
- 성능, 표준
생산성 - JPA와 CRUD
- 저장: jpa.persist(member)
- 조회: jpa.find(memberId)
- 수정: jpa.setName("변경할 이름")
- 삭제: jpa.remove(member)
유지보수
- 기존에는 필드 변경시 모든 SQL를 수정
- JPA는 필드만 추가하면 되고, JPA가 SQL를 처리해준다
패러다임 불일치 해결
- 상속: JPA에서 부모 클래스를 저장, 조회해주면 JPA가 알아서 처리해준다
- 연관관계, 객체 그래프 탐색
신뢰할 수 있는 엔티티, 계층
JPA는 동일한 트랜잭션에서 조회한 엔티티는 같음을 보장해준다
JPA의 성능 최적화 기능
- 1차 캐시와 동일성 보장 (엄청 성능을 최적화하지는 않는다고 한다)
같은 트랜잭션 안에서는 같은 엔티티를 반환
DB Isolation Level이 Read Commit이어도 애플리케이션에서 Repeatable Read 보장
- 트랜잭션을 지원하는 쓰기 지연
트랜잭션을 커밋(commit)할 때까지 INSERT SQL을 모음
UPDATE, DELETE로 인한 ROW LOCK 시간 최소화
- 지연 로딩(Lazy Loading)
지연 로딩: 객체가 실제 사용될 때 로딩
즉시 로딩: JOIN SQL로 한번에 연관된 객체까지 미리 조회
ORM은 객체와 RDB 두 기둥위에 있는 기술
JPA 시작하기
- H2 Database 설치(교육용)
- pom.xml 이나 build.gradle에 외부 라이브러리 설치
- persistence.xml 파일 설정 : 각 DB에 맞게 Dialect 설정 가능(H2, MySQL, Oracle 등)
JPA 구동 방식
Member 객체 생성
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Member {
@Id
private Long id;
private String name;
//Getter, Setter
}
- @Entity: JPA가 관리할 객체
- @Id : 데이터베이스 PK와 매핑
JPA Main Class 작성
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
tx.commit();
em.close();
emf.close();
}
- EntityMangerFactory는 하나만 생성해서 애플리케이션 전체에서 공유
- JPA의 모든 데이터 변경은 트랜잭션 안에서 실행
- try-catch-finally 문으로 짜는 것이 정석적인 코드
JPQL 소개
- 동적 쿼리 ex) 나이가 18살 이상인 회원을 모두 검색하고 싶다면?
- JPA를 사용하면 엔티티 객체를 중심으로 개발하지만 문제는 검색 쿼리
- 검색을 할 때에는 테이블이 아닌 엔티티 개체를 대상으로 검색
- 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능 (SQL이 필요)
- JPA는 SQL을 추상화한 JPQL이라는 객체지향 쿼리 언어 제공 (SQL과 문법 유사)
- JPQL은 엔티티 객체를 대상으로 쿼리, SQL은 DB 테이블 대상으로 쿼리
- 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
- JPQL은 객체 지향 쿼리
출처 : 자바 ORM 표준 프로그래밍
'Back-end Programming > JPA' 카테고리의 다른 글
JPA 고급 매핑 (0) | 2021.04.17 |
---|---|
JPA 다양한 연관관계 매핑 (0) | 2021.04.17 |
JPA 연관관계 매핑 기초 (0) | 2021.04.16 |
JPA 엔티티 매핑(Entity Mapping) (0) | 2021.04.15 |
JPA 영속성 관리 - 내부 동작 방식 (0) | 2021.04.14 |