1. 소개

JAVA 진영의 ORM 표준.

스프링 기반의 실무에서는 Spring Data JPA를 주로 사용하여 개발하며 Hibernate 구현체를 대부분 많이 사용합니다.

JPA, Spring Data JPA, Hibernate 관계에 대해 조금 쉽게 설명하면 Hibernate는 JPA 구현체이고

Spring Data JPA는 Spring 프레임워크에서 JPA를 다루기 쉽게 구현된 것이라 생각하면 됩니다.

Spring Data JPA는 Hibernate만을 구현체로 사용하지 않고 여러 다른 구현체를 선택할 수 있습니다.

하지만 대부분 Hibernate를 구현체로 사용하고 있기때문에

이런 관계에 대해서 많이 혼동이 있는 분들이 많은 것 같습니다.

JPA, Spring Data JPA, Hibernate 가 혼동된다면 아래 이미지를 보며 어느 정도 관계에 대해서 이해가 쉬울 것 같습니다.

 

 

2. ORM(Object-relational mapping) 

객체와 관계형 데이터베이스를 맵핑하는 기술.

객체는 객체대로 설계하고 RDBMS는 RDBMS대로 설계하고 ORM 프레임워크가 중간에서 맵핑.

 

3. 기존 SQL 중심 개발의 문제점

public Class User {
	private String userId;
    private String userName;
    private String email;
    private UserGroup userGroup;
}
public Class UserGroup {
	private String groupId;
    private String name;
}

두 개의 참조 관계의 객체들이 있다면 조인하여 데이터를 얻을 수 있는

SQL을 조회 개발이 필요하고 SQL문의 조회 결과를 각각의 두 개의 객체에 결과를 다음과 같이 맵핑해줘야 합니다.

SELECT U.*, UG.*
  FROM USER U JOIN USER_GROUP UG ON U.groupId = UG.groupId
public User findUser(String userId) {
	// SQL 실행 결과를 아래의 객체에 세팅
    User user  = new User();
    user.setUserName(name);
    		...
    UserGroup userGroup = new UserGroup();
    user.setGroupName(name);
    		...
    // 회원과 그룹의 관계 세팅
    user.setUserGroup(userGroup);
    return user;
}

 

 

이런 맵핑 작업이 계속 필요하기 때문에 생산성이 떨어지다 보니 하나의 객체로 처리할 수 있게 DTO를 만들어서

조회 결과에 대해 setter/getter 처리하는 경우 많습니다.

그런데 이런 경우 SQL 문에 SELECT 필드에 따라서 데이터가 있을 수도 없을 수도 있는 경우가 발생하게 됩니다.

그러다 보니 일반적으로 MVC model을 사용하여 계층적으로 분리를 많이 하지만 논리적으로는 얽혀있는 상태가 되면서

SQL 문까지 전부 확인하기 전까지는 슈퍼 DTO(객체)의 데이터가 없어서 안 들어간 것인지 필요가 없어서 뺀 것인지

신뢰하기 어렵기 때문에 여기서 또 개발에 생산성과 유지보수가 점점 어려워지게 됩니다

문제는 객체지향 모델링할수록 이런 맵핑 작업이 늘어나게 되고

그러다 보니 SQL 문에 맞춰서 객체를 설계하는 경우가 많아지게 되면서 생산성은 떨어지게 되는 악순환이 반복됩니다.

또 다른 경우를 확인해보면 예를 들어 어떤 기능을 개발한다고 가정하면 관련 CRUD SQL에 생성이 필요하고

이렇게 생성한 상태에서 DB 테이블에 칼럼 하나가 추가된다고 하면 관련된 SQL 문 모두 수정 필요합니다.

번거롭고 생산성이 떨어지는데 혹시 실수로 하나라도 추가나 수정해야 할 필드를 SQL문에서

놓치게 되면 에러가 발생하게 됩니다.

 

4. JPA를 활용한 해결

이런 문제들에 대해서는 JPA는 솔루션이될 수 있습니다.

별도의 SQL 문 작성 없이 객체 관계 설정을 통해 SQL 문을 생성해주므로 단순히 JPA에 정의한 CRUD 메서드를 

사용하여 생산성을 높일 수 있습니다.

지연 로딩 기능을 활용해 조인 관계 놓인 객체 데이터라고 해도 객체가 조회되는 시점에 SQL을 생성/조회할 수 있고

만약 항시 채워진 데이터가 필요할 경우 옵션 설정을 통한 즉시 로딩 기능으로 데이터를 모두 하나의 SQL을 생성/조회할 수 있습니다.  이런 기능을 활용하여 맵핑을 위한 복잡한 추가 코딩을 줄일 수 있습니다.

모든 부분이 직접적인 SQL 작성 없이 처리할 수 없는 경우를 처리하기 위한 SQL과 유사한 JPQL를 사용하여 조회할 수 있게 만든 기능도 있습니다.

 

5. 마치며

간단하게 개념과 기존 SQL 중심 개발의 문제점과 JPA에 어떤 해결방법이 있는지 확인해보았습니다.

다음 글에서는 영속적 콘텍스트와 4번 항목에서 말한 지연 로딩 같은 솔루션에 대한 예제를 살펴보겠습니다.

 

※ 참고

https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html

https://suhwan.dev/2019/02/24/jpa-vs-hibernate-vs-spring-data-jpa/ 

자바 ORM 표준 JPA 프로그래밍 / 김영한 저자

'Java > JPA' 카테고리의 다른 글

JPA (Java Persisitence API) - JPA 영속성 관리 (2)  (0) 2022.05.17

+ Recent posts