# JPA(Java Persistence API), ORM(Object-Relational Mapping)은 무엇인가?
JPA는 자바 ORM 기술 표준으로서, 애플리케이션과 JDBC 사이에서 동작한다.
ORM은 객체와 '관계형 데이터베이스를 매핑'한다는 의미이다.
# ORM 프레임워크 특징
- 개발자가 조회/저장/수정/삭제 작업을 위해 SQL문을 직접 작성하지 않고, 자바 컬렉션 다루듯이 사용할 수 있다.
- 객체와 테이블을 매핑해서 패러다임의 불일치 문제를 개발자 대신 해결해 주는 역할을 수행한다.
- 개발자는 데이터 중심인 관계형 데이터베이스를 사용해도 애플리케이션 개발에만 집중할 수 있다.
# 패러다임의 불일치
객체와 관계형 데이터베이스는 지향하는 목적이 서로 다르므로 둘의 기능과 표현 방법이 다르다. 따라서 객체 구조를 데이터 구조에 저장하는 데 한계가 생기게 되는데, 이것을 객체와 관계형 데이터베이스의 패러다임 불일치 문제라고 한다.
1. 상속 문제
객체는 상속이라는 기능을 가지고 있지만, 테이블은 상속이라는 기능이 없다.
public abstract class Shiba {
Long id;
String name;
Long age;
}
public class BlackShiba extends Shiba {
String color;
}
BlackShiba 객체를 저장하려면, 이 객체를 분해해서 2가지 SQL문을 만들어야 한다.
INSERT INTO SHIBA ...
INSERT INTO BLACKSHIBA ...
만약 JDBC API를 사용해서 해당 작업을 완성하려고 한다면, 부모 데이터 관련하여 SQL 코드를 작성하고, 자식 데이터에 관련해서도 SQL 코드를 작성해야 하는데.. 이러한 일이 반복되면 생산성이 굉장히 떨어질 것은 분명하다.
JPA는 상속과 관련된 패러다임의 불일치 문제를 대신 해결해 준다. 개발자는 자바 컬렉션에 객체를 저장하듯이 단순하게 JPA에 객체를 저장하면 된다.
2. 연관관계 문제
* 차이점 - 1
객체는 참조를 사용해서 다른 객체와 연관관계를 가지고 참조에 접근해서 연관된 객체를 조회한다.
테이블은 외래 키를 사용해서 다른 테이블과 연관관계를 가지며, 조인을 사용해 연관된 테이블을 조회한다.
* 차이점 - 2
객체는 참조가 있는 방향으로만 조회할 수 있다.
테이블은 외래 키 하나로 조인한 반대 방향 테이블도 조회 가능하다.
JPA는 특정 객체의 참조를 외래 키로 변환해서 적절한 SQL을 데이터베이스에 전달하므로 연관관계에 대한 패러다임 불일치 문제를 해결해 준다.
3. 객체 그래프 탐색
객체에서 참조를 통해 연관된 객체들을 탐색하는 것을 객체 그래프 탐색이라고 한다.
객체는 마음껏 객체 그래프를 탐색할 수 있어야 하는데, 관계형 데이터베이스에서도 가능할까?
SQL을 직접 다루면 조인하여 가지고 온 테이블만 객체에서 조회가 가능하기 때문에 처음 실행하는 SQL에 따라서 객체 그래프를 어디까지 탐색할 수 있을지 정해진다.
이런 제한된 탐색은 개발자 입장에서 큰 제약이 된다. 왜냐하면, 비즈니스 로직에 따라 사용하는 객체 그래프가 다른데 언제 끊어질지 모를 객체 그래프를 함부로 탐색할 수가 없기 때문이다. 따라서 해당 객체가 존재하는지 확인하기 위해 모든 객체 참조 시 보호 절을 작성해야 한다.
BlackShiba shiba = new BlackShiba();
// 주의! shiba.getGroup() null일 수 있음.
if(Objects.nonNull(shiba.getGroup())) {
shiba.getGroup(); // null ?
}
코드만 보고는 객체 그래프를 탐색할 수 있을지 없을지 예상이 불가능하다.
따라서, 객체 그래프 탐색이 가능한지 확인을 위해 코드 작성 시마다 SQL을 직접 확인해야 하는 불편함을 감수해야 한다.
JPA를 사용하면 객체 그래프를 자유롭게 탐색 가능하다. JPA는 연관된 객체를 '사용하는 시점'에 적절한 SELECT SQL을 실행하기 때문이다. 따라서 JPA를 사용하면 연관된 객체에 대한 SQL을 확인해야 하는 불편함 없이 안전한 코드 작성이 가능하다.
4. 비교
객체는 동일성 비교, 동등성 비교를 통해 객체를 비교한다.
- 동일성 비교는 == 를 통해 객체 인스턴스의 주소 값을 비교한다.
- 동등성 비교는 equals() 메서드를 사용해 객체 내부의 값을 비교한다.
데이터베이스는 기본 키의 값으로 각 로우를 구분한다.
기존 JDBC API를 사용하는 경우에는 새로운 객체를 생성하기 때문에, 데이터베이스에서 동일한 raw를 불러와도 인스턴스의 주소 값을 비교하는 동일성 비교에서 false가 반환된다. 객체 측면에서는 다른 인스턴스이기 때문이다.
만약 객체를 컬렉션에 저장했다면? 같은 인스턴스 주소를 가지고 있기 때문에, 동일성 비교에서도 성공했을 것이다.
JPA는 같은 트랜잭션일 때 같은 객체가 조회되는 것을 보장하는 특징을 가지고 있다. 따라서 동일성 비교에 성공한다.
# JPA를 사용해야 하는 이유?
- 생산성
- JPA를 사용하면 자바 컬렉션에 객체를 저장하듯이 JPA에 저장할 객체를 전달하면 된다. 따라서 JDBC API를 사용하는 지루하고 반복적인 일을 JPA가 대신 처리해 준다.
- 유지보수
- 기존에는 Entity의 필드를 추가하거나 수정하면 관련된 모든 SQL 문과 결과 매핑을 위한 JDBC API를 모두 변경해야 했지만 JPA를 사용하면 이런 과정을 JPA가 대신 처리해 준다.
- 패러다임의 불일치 해결
- JPA는 상속, 연관관계, 객체 그래프 탐색, 비교하기와 같은 패러다임의 불일치 문제를 해결해 준다.
- 성능
- JPA는 애플리케이션과 데이터베이스 사이에서 다양한 성능 최적화 기회를 제공한다. 예를 들면 데이터베이스의 동일한 데이터를 재조회 했을 경우, 영속성 콘텍스트에 담긴 정보를 그대로 반환하는 캐싱 기능 등이 있다.
- 표준화
- JPA는 자바 ORM 기술 표준이다. 표준을 사용하면 다른 구현 기술로 손쉽게 변경할 수 있다는 장점이 있다.
REFERENCE
- (도서) 자바 ORM 표준 JPA 프로그래밍
'Spring > JPA' 카테고리의 다른 글
Spring Boot 3.0 QueryDsl Maven 설정하기 (0) | 2023.04.09 |
---|---|
JPA 동일 트랜잭션에서 update와 insert 동시에 수행할 때 문제 해결하기 (쿼리 실행 순서 문제) (0) | 2023.02.05 |
JPA @Where 일괄 조회 사용법 및 문제점과 해결방안 (0) | 2023.01.24 |
JPA @Query @Modifying 벌크 삭제 연산시 연관관계 문제 해결하기 (with SQLIntegrityConstraintViolationException) (0) | 2023.01.22 |
JPA @Query @Modifying 벌크 연산시 자동 업데이트(Auditing) 주의사항 (0) | 2023.01.15 |
댓글