티스토리 뷰

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
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함