[JPA]JPA 사용 목적

Inung_92·2023년 9월 22일
1

JPA

목록 보기
1/7
post-thumbnail

해당 포스팅의 내용은 김영한 강사님의 자바 ORM 표준 JPA 프로그래밍 책의 내용을 정리하여 작성하였습니다.


포스팅 목적

JPA의 개념을 알아보고, JPA의 사용이 객체지향 프로그래밍과 어떤 관계가 있는지에 대해서 알아보자.

JPA란?

JPA(Java Persistance API)는 자바 진영의 ORM 표준 기술로 애플리케이션과 JDBC 사이에서 동작한다. 즉, 자바 ORM 기술에 대한 API 표준 명세이다.

여기서 ORM이 무엇인지에 대해 먼저 살펴보고 넘어가자.

ORM

ORM(Object-Relational Mapping)은 객체와 관계형 데이터베이스를 매핑하는 것을 의미한다. 즉 객체와 테이블을 개발자 대신 매핑하여 객체중심의 개발이 가능하도록 보조하는 역할을 한다. 대표적인 프레임워크로 Hibernate가 있다.

ORM의 동작 원리를 간단하게 표현하면 다음과 같은 순으로 동작한다.

  • 객체 저장 요청
  • ORM 프레임워크에 객체 저장
  • ORM 프레임워크가 직접 SQL을 생성하여 DB에 저장

ORM을 사용하게되면 개발자는 객체 모델링에 집중 할 수 있고, 데이터베이스는 데이터 중심의 설계를하면된다. 그리고 이렇게 객체와 데이터베이스를 매핑하는 방법만 ORM에게 전달하면 되는 것이다.

ORM에 대해서 간단히 알아보았으니 왜 JPA를 사용해야하는지에 대해서 알아보자.

JPA를 사용해야하는 이유

JPA를 사용하는 것에 대해서는 여러가지 이유가 있겠지만 다음과 같은 이유가 대표적이다.

  • 생산성
    개발자는 자바 컬렉션에 객체를 저장하듯이 JPA에 객체를 저장하고, JDBC에 쿼리를 작성하는 반복적인 일을 JPA가 대신 처리한다.
  • 유지보수
    SQL을 직접 핸들링하면 필드가 하나 추가 될 경우 JDBC API 코드를 대부분 수정해야 했으나 JPA를 사용하면 객체 단위로 데이터가 전달되기에 SQL을 건드릴 필요가 없다.
  • 성능
    애플리케이션과 데이터베이스 사이에서 동작하여 다양한 성능 최적화 기회를 제공한다. 예를 들어 동일한 데이터를 조회할 경우 먼저 SELECT로 가져온 객체를 두번째 쿼리를 실행 할 필요없이 재사용 할 수 있다.
  • 데이터 접근 추상화와 벤더 독립성
    여러 데이터베이스 벤더들의 기술에 종속되지 않고, 방언을 통해 각 벤더의 특징을 해결할 수 있다.

위에서 언급한 이유들도 좋지만 JPA를 사용해야하는 가장 큰 이유는 패러다임의 불일치를 해결하기 위함이라고 할 수 있다.

패러다임 불일치

지속가능한 애플리케이션을 개발하는 일은 증가하는 복잡성과의 싸움

이러한 복잡성을 해결하기 위해서 객체지향 프로그래밍은 추상화, 캡슐화, 정보은닉, 상속, 다형성 등의 특징을 통해 시스템을 제어할 수 있다. 하지만 데이터 중심의 설계로 인해 객체지향의 특징을 활용 할 수 없다는 문제가 있다.

주요 문제가 되는 부분은 다음과 같다.

  • 상속
    객체는 상속이라는 기능을 통해 상위 객체의 속성 및 기능을 하위 객체에서 사용이 가능하지만 테이블은 상속이라는 개념이 없다. 그렇기 때문에 연관성이 있는 테이블을 조회하기 위해서는 추가적인 쿼리 작성 등의 노력이 필요하다.

    // 객체 모델 코드
    abstract class Item{
    	long id;
      	String name;
      	int price;
    }
    
    class Album extends Item{
    	String artist;
    }
    
    class Movie extends Item{
    	String director;
      	String actor;
    }
    ...

    위와 같이 객체를 정의하였고, 데이터베이스에 저장하기 위해서 다음과 같이 쿼리를 작성한다.

    INSERT INTO ITEM...
    INSERT INTO ALBUM...

    Moive 객체도 마찬가지다. 이렇게 분해해서 SQL을 생성하여 저장하고, 조회할 때는 또 다른 쿼리가 추가적으로 작성된다. 하지만 이런 부분을 자바 컬렉션에 저장한다고 가정하면 다음과 같다.

    list.add(album);
    list.add(movie);
    ...
    
    // 조회
    Album album = list.get(albumId);

    JPA는 이러한 부분들에 대해서 중간에서 매핑하는 역할을 통해 패러다임 불일치를 해결하는데 도움을 준다.

    // 객체 저장
    jpa.persist(album);
    
    // JPA 내부에서 객체를 2개의 테이블로 나누어 저장하고, 쿼리를 자동으로 생성한다.
    
    // 객체 조회
    String albumId = "id01";
    Album album = jpa.find(Album.class, albumID);

    위와 같이 객체를 저장하고 조회하는 것을 JPA의 함수를 활용하고, JPA는 함수를 동작하며 해당하는 쿼리를 생성하여 처리해주는 것이다.

  • 연관관계
    객체는 참조(주소)를 통해 연관된 객체의 조회가 가능하다. 반면 테이블은 외래 키를 통해 조인을 사용해 연관된 테이블을 조회 할 수 있다. 관계형 데이터베이스는 조인이라는 기능을 통해 연관된 테이블의 정보를 가져올 수 있지만 객체를 통해 이를 구현하기 위해서는 연관된 필드를 클래스 내에 보유하고, 해당 필드를 통해 쿼리를 반복적으로 작성해야하는 불편함이 발생한다.

    // 연관관계
    class Member {
    	Team team;
       ...
       Team getTeam(){
       	return team;
       }
    }
    
    class Team {
    	...
    }

    Member는 Team의 참조를 보관하여 아래와 같이 팀에 접근 할 수 있다.

    Team team = member.getTeam();

    하지만 데이터 중심으로 설계된 테이블을 기준으로 연관된 정보를 획득하려면 다음과 같이 코드가 작성된다.

    class Member{
    	String id;
       Long teamId;
       String userName;
    }
    
    class Team{
    	Long id;
       ...
    }

    위와 같은 코드에서는 getTeam()이라는 메소드가 없을 뿐더러 참조를 통한 연관된 정보를 획득하는 것이 제한된다. 따라서 조인을 통한 쿼리를 작성하거나 해당하는 Member가 보유한 teamID를 통해 쿼리를 한번 더 작성하고 실행해야하는 불편함이 생긴다.

  • 객체 그래프 탐색
    객체 그래프 탐색은 객체 지향에서 필수적이라고 할 수 있지만 SQL을 직접 다루면 처음 실행하는 SQL에 따라 객체 그래프의 큰 제약이 발생하게 된다. 객체 그래프가 언제 끊어질지 모르기 때문에 함부로 탐색하면 비용이 낭비되기 때문이다.

    // 그래프 탐색
    member.getTeam().getTeamCar();

    객체 그래프를 탐색하는 코드이다. 이 부분을 쿼리로 조회한 결과로 탐색한다면 어떻게 될까?

    SELECT M.*, T.* FROM MEMBER M JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
    
    // 그래프 탐색
    member.getOrder();
    null

    getTeam()에 대한 결과는 가져올 수 있지만 객체가 가진 다른 참조 객체에 대해서는 확인 할 수 없다. JPA를 활용하면 객체 그래프를 탐색 할 수 있도록 지연 로딩을 투명하게 처리한다.

  • 비교
    데이터베이스는 기본 키 값으로 각 행을 구분한다. 반면 객체는 동일성과 동등성 비교가 가능하다. 데이터베이스에서는 동일한 값을 가진 행을 가져와도 동일성 비교가 실패된다. 새로운 인스턴스를 생성한 것으로 판단하기 때문이다. 하지만 JPA는 같은 트랜잭션일 때 같은 객체가 조회되는 것을 보장한다. 즉, 동일성 비교가 성공한다.

위에서 이야기한 부분들이 패러다임 불일치의 주요 내용들이며, 이를 해결하기 위해 개발자들의 노력과 반복적인 업무가 수반된다.

이러한 문제를 해결하기 위해서 애플리케이션과 데이터베이스 사이에서 동작하는 JPA를 활용하는 것이다.


마무리

이번 포스팅에서는 실제 JPA를 사용하기 전에 JPA가 무엇이고, 왜 사용해야하며 JPA를 사용하지 않을 때 발생하는 부분들에 대해서 알아보았다.

다음 포스팅부터 실제로 JPA를 사용하면서 상세하게 뜯어보며 알아가보도록하자.

그럼 이만.

profile
서핑하는 개발자🏄🏽

0개의 댓글