[ JPA ] JPA와 패러다임 불일치

5tr1ker·2023년 6월 12일
0

JPA

목록 보기
1/2
post-thumbnail

JPA란?

JPA는 Java Persistence API의 약자로 자바 진영의 ORM 기술 표준입니다. JPA는 JDBC 와 어플리케이션 사이에서 동작합니다.

JPA를 사용해야 하는 이유

1. 생산성

JPA를 사용하면 자바 컬렉션처럼 데이터베이스에 저장할 객체를 persist() 메서드를 통해 전달해주기만 하면 됩니다. 그러면 JPA는 적절한 Insert SQL 문을 실행하고 JDBC API 도 대신 처리해줍니다. 따라서 반복적은 CRUD SQL문을 작성하지 않아도 돼며 DDL 문을 자동으로 생성해줍니다.

2. 유지보수

SQL에 의존적인 개발을 진행하면 엔티티에 필드가 수정됐을 경우 SQL Mapper 부터 JDBC API 코드를 모두 변경해야 합니다. 반면에 JPA는 이러한 과정을 대신 처리함으로써 필드를 수정해도 변경해야 할 코드의 수가 줄어듭니다.

3. 패러다임 불일치 해결

JPA는 객체와 데이터베이스 사이의 지향하는 목적이 달라 발생할 수 있는 문제를 해결해 줌으로 써 유연하고 유지보수하기 좋은 도메인 모델을 설계할 수 있습니다.

4. 성능

JPA는 어플리케이션과 데이터베이스 사이에 위치하여 다양한 최적화 기회를 제공합니다. 예를 들어 같은 SQL문을 실행했을 때 캐시에 저장된 객체를 반환하여 데이터베이스와 통신하는 비용을 아낄 수 있습니다. 또한 하이버네이트는 SQL 힌트를 넣을 수 있는 기능도 존재합니다.

5. 데이터 접근 추상화와 벤더 독립성

관계형 데이터베이스는 같은 기능도 벤더마다 사용법이 다른 경우가 많습니다. 따라서 어플리케이션은 처음 선택한 데이터베이스 기술에 종속되고 다른 데이터베이스로 바꾸는 것이 어렵습니다.
하지만 JPA는 데이터 접근 계층을 제공하여 특정 데이터베이스에 종속되지 않으며 어떤 데이터베이스를 사용할 것인지 설정만 하면 됩니다.

ORM ( Object-Relation Mapping )

ORM은 이름 그대로 객체와 데이터베이스 테이블을 매핑한다는 뜻으로 ORM 프레임워크는 객체와 테이블 사이의 패러다임 불일치를 해결해 줄 수 있습니다.

ORM 프레임워크를 사용하면 객체를 데이터베이스에 저장할 떄 Insert SQL 를 직접 작성하는 것이 아니라 ORM 프레임워크에서 제공하는 메서드를 활용해 마치 컬렉션에 저장하듯이 값을 설정하면 ORM 프레임워크는 적절한 SQL를 실행하여 데이터베이스에 값을 넣습니다.

ORM 프레임워크에는 다양한 프레임워크가 존재하는데 여기서 하이버네이트가 가장 많이 활용되는 프레임워크입니다.

패러다임 불일치

패러다임 불일치는 객체와 관계형 데이터베이스는 지향하는 목적이 서로 다르므로 둘의 구조와 표현 방법이 다른것을 말합니다.
객체는 객체 지향인 다형성 , 추상화 , 상속의 성질을 갖고 있으며 연관관계를 참조를 이용해 참조합니다. 반면에 데이터베이스는 데이터 중심으로 구조화되어 있으며 연관관계를 외래키를 이용하여 참조합니다.
이러한 패러다임 불일치는 개발자가 중간에서 해결해 주어야하며 더 많은 시간과 코드를 소비하는 단점이 존재합니다.

상속

객체는 상속이라는 개념을 갖고 있지만 테이블은 상속이라는 개념이 없습니다. 그나마 데이터베이스 모델링 중 슈퍼 타입과 서브 타입 관계를 사용하여 테이블과 유사한 형태로 만들 수 있습니다.

위와 같은 그림으로 상속을 하는 ITEM은 테이블의 DTYPE 컬럼으로 자식 테이블의 관계를 표현합니다.
여기서 ALBUM 객체를 저장하려면 이 객체를 분리해서 ITEM 과 ALBUM 테이블에 각각 값을 넣어주어야 하며 , 반대로 값을 조회할 때에도 두 테이블을 조인하여 Album 객체에 값을 넣어 반환해야 합니다.

반면 JPA를 사용한다면 해당 객체를 persist() 메서드를 이용해 저장을 하면 연관된 참조를 같이 저장하며, find()를 통해 검색을 할 때에도 연관된 객체를 함께 조회할 수 있습니다.

연관 관계

객체는 참조를 사용해서 다른 객체와 연관관계를 맺고 , 테이블은 외래키를 이용해서 다른 테이블과의 연관관계를 맺습니다. 또한 참조는 단 방향으로만 가져올 수 있지만 , 테이블은 양 방향으로 데이터를 조회할 수 있는 차이가 있습니다.

이를 해결하기 위한 방법으로 객체를 데이터베이스에 저장할 때 참조 관계의 기본키값을 가져와 데이터베이스의 외래키로 저장하며 조회할 때는 각각 조회 후 객체에 담아 setter 로 참조관계를 만들어 주어야 합니다.

하지만 JPA에서는 setter를 이용해 연관 관계를 만들고 저장을 하면 자동으로 참조를 외래키로 변환해서 적절한 SQL문을 실행하며, 조회할 때는 외래키를 참조로 변경해 줍니다.

객체 그래프

객체 그래프는 자바에서 참조를 사용해서 연관된 객체를 찾을 수 있는 것을 말합니다.

Order order = team.getTeam().getMember().getOrder();

객체는 마음껏 객체 그래프를 탐색할 수 있어야 합니다. 하지만 데이터베이스에서는 연관된 데이터를 조회하지 않았다면 탐색할 수 없습니다. ( null )
SQL을 직접 작성하여 객체 그래프를 어디까지 탐색할지 정할 수 있지만 이는 객체지향 프로그래머에게 큰 제약이 됩니다. 그 이유는 비즈니스 로직에 따라 객체 그래프의 탐색 범위가 다르기 때문입니다.

이에 JPA를 사용하여 객체 그래프를 마음껏 탐색할 수 있게 합니다. 이는 JPA가 연관된 객체를 직접 사용하는 시점에 SELECT SQL문을 실행하며, 이 기능은 객체가 사용되는 시점까지 조회를 미루는 지연 로딩 를 나타냅니다.

비교

데이터베이스는 기본키값으로 row를 구분하지만, 객체는 동일성 ( == ) 과 동등성 ( .equal() ) 를 이용하여 비교를 합니다.

JDBC를 사용하여 같은 키값을 두 번 조회하면 다른 인스턴스를 생성해 ( new 연산자 ) 반환하기 때문에 동일성 비교에 실패를 합니다.

이런 패러다임 불일치를 해결하기 위해서 JPA는 동일 트랜잭션에서 같은 행을 조회할 때 동일한 객체를 반환하는 것을 보장합니다.

참고

자바 ORM 표준 JPA 프로그래밍 ( 김영한 )

profile
https://github.com/5tr1ker

0개의 댓글