JPA(Java Persistence API)

이동영·2024년 3월 18일

JPA

목록 보기
3/8

JPA를 왜 사용할까?

JPA의 사용 목적을 알기 위해 먼저 자바에서 데이터베이스를 어떻게 사용할 까?

  • 자바로 작성한 애플리케이션은 JDBC API를 통하여 SQL을 데이터베이스에 전달하고 받는다.
  • JDBC를 사용하기 위해 JDBC라이브러리를 항상 자바 애플리케이션에 추가해야 한다.
  • SQL문을 코드로 작성하고 JDBC API로 데이터베이스에 전달한다. 이를 보통 애플리케이션과 데이터베이스 사이에 JDBC API를 두고 개발한다.

무엇보다 SQL을 직접 작성해야 하는 번거로움이 있으며 오타가 발생하게 되면 그것을 해결하기 위해 시간을 투자해야 하며 그 결과를 확인해야 하는 작업을 해야한다.

패러다임 불일치 문제

JPA를 사용하면 단순히 코드가 짧아지는 것만 있는것이 아니다. 객체지향과 관계형 데이터베이스 사이의 패러다임 불일치 문제를 해결할 수 있기 때문이다.

패러다임 불일치란?

객체지향 프로그래밍은 추상화 캡슐화, 상속, 다형성등이 대표적인 특징이 있다. 이러한 객체 데이터를 보관하기 위해 데이터베이스에 저장해야 하는데 관계형 데이터베이스에 객체를 저장하게 된다. 관계형 데이터베이스는 행과 열로 구성된 테이블 구조이며 객체에 있는 추상화 상속 다형성등의 개념이 없다.

관계형데이터베이스는 객체와는 엄연히 다른 방식이다. 이처럼 객체와 관계형 데이터베이스의 지향하는 목적이 달라 기능과 표현 방법의 차이가 발생하는 문제를 패러다임 불일치
문제라고 한다.

패러다임 불일치의 문제?

1. 상속

객체지향의 상속을 데이터베이스에서 사용하기 위해 슈퍼타입과 서브타입을 이용해 유사한 형태로 테이블을 설계할 수 있다.


JDBC API 혹은 Mybatis를 활용하여 저장 및 조회를 하기 위해 각 테이블에 접근하는 쿼리문을 각각 만들어 줘야 한다. 이는 시간도 걸리며 쿼리문에 오타가 발생하면 시간은 배로 증가하게 된다.

하지만 JPA를 사용하면 자바 컬렉션에 객체를 저장하듯 JPA에 객체를 저장할 수 있다.

jpa.persist(album); //저장하기

String albumId = "id100";
Album album = jpa.find(Album.class, albumId); //조회하기

우리가 작성하는 코드는 줄어들게 된 것이며, 내부적으로JPA는 두 개의 SQL문을 사용하여 객체를 두 테이블에 나누어 저장하게 된다. 데이터를 조회할 때도 두 테이블을 조인해서 필요한 데이터를 조회한다.

정리 : 객체에 맞게 설계를 하면 JPA가 알아서 관계형 디비에 맞도록 변환하여 알아서 코드를 작성해준다.

2. 연관관계

객체와 테이블 모두 관계를 가질 수 있는데 연관관계를 갖고 조회하는 방식은 서로 다르다.

객체의 연관관계
  • 참조를 사용해 연관관계를 가짐
  • 참조에 접근해 연관 객체 조회
테이블의 연관관계
  • 외래키를 사용해 연관관계 가짐
  • 조인을 사용해 연관 테이블 조회
  • 외래키로 양방향 조회 가능

이처럼 객체의 참조와 테이블의 연관관계 방식이 다르기 때문에 개발자가 직접 해줘야 하는 작업을 수행하지만 JPA를 활용하면 객체지향적으로 코드를 작성할 수 있으며 그 외 참조와 외래키 변환은 JPA가 알아서 처리해준다.

class Member {
		String id;
		Long teamId; //FK 컬럼
		String username;
}

class Team {
		Long id;
		String name;
}

이렇게 객체 모델을 만들면 당연하게도 다음과 같이 참조를 통한 연관 객체를 찾을 수 없다. 이러한 설계는 객체지향적이지 않으면서 객체를 데이터 전송용으로만 사용하는 것이다.

Team team = member.getTeam();

그렇다면 참조를 통해 관계를 맺는 객체지향의 방식으로 객체를 모델링 한다면?

class Member {
		String id;
		Team team; //참조로 연관관계를 맺음
		String username;

		Team getTeam() {
				return team;
		}
}

class Team {
		Long id;
		String name;
}

이 방식이 객체가 다른 객체를 참자하는 코드이다. 이렇게 설계할 경우 개발자가 중간에서 참조 모델을 외래키로 변환하고, 외래키를 참조 모델로 변환해주는 역활을 수행하기에 쿼리지향적이게 된다. 하지만 이 과정을 JPA사용시 알아서 처리해준다.

JPA를 사용하면 다음과 그저 객체지향 방식대로 진행하여 메소드를 호출해주면 된다.

Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam();

3. 객체 그래프 탐색

  • 위에 살표본 예제처럼 참조를 사용하여 연관된 객체를 찾는 것을 객체 그래프 탐색이라고 한다.
  • 객체는 자유롭게 객체 그래프를 탐색할 수 있어야 한다.
  • SQL을 직접 다루면 처음 실행하는 SQL에 따라 객체 그래프 탐색 범위가 정해지게 된다.
  • 그래프 탐색 범위를 알아보기 위해 데이터 접근 계층 DAO를 열어 직접 확인해야 하는, 엔티티가 SQL에 종속된다.

이 때 JPA를 활용하면 다음과 같이 객체 그래프를 원하는 만큼 탐색이 가능하다.

member.getOrder().getOrderItem()...

4. 객체의 비교

객체는 두가지의 방법으로 비교할 수 있다.

  • 동일성 비교(==); 객체 인스턴스의 주소 값 비교
  • 동등성 비교 (equals()); 객체 내부 값 비교
    JDBC API로 데이터를 조회하는 find()메소드를 정의하고 객체를 조회하게 되면 동일성 비교는 실패하게 된다.
String memberId = "100";
Member m1 = memberDAO.find(memberId);
Member m2 = memberDAO.find(memberId);

m1 == m2; //false

m1 과 m2는 디비 상 같은 row에서 조회되었지만, 객체 입장에서는 전혀 다른 인스턴스 이기 때문이다.

이와 달리 JPA에서는 같은 트랜젝션일 경우 같은 객체가 조회되는 것을 보장하기 때문에 동일서 비교도 가능하다.

String memberId = "100";
Member m1 = jpa.find(Member.class, memberId);
Member m2 = jpa.find(Member.class, memberId);

m1 == m2; //true

JPA란 무엇인가?

  • 자바에서 사용하는 ORM(Object Relational Mapping)기술 표준이다.
  • 자바 애플리케이션과 JDBC사이에서 동작하며, 자바 인터페이스로 정의 되어 있다.
  • JPA는 인터페이스이기 때문에 구현체가 필요한데 JPA의 구현체는 Hibernate, EclipseLink, DataNucleus가 있는데 대표적으로 Hibernate를 사용한다.

ORM(object Relational Mapping)

  • ORM은 객체와 관계형 데이터베이스를 매핑해주는 기술로 객체는 객체대로 테이블은 테이블대로 설계할 수 있도록 ORM 프레임워크가 중간에서 매핑을 하여 패러다임의 불일치 문제를 해결해주는 역활을 수행한다.

JPA의 동작과정

JPA는 JAVA 애플리케이션과 JDBC사이에서 동작하는데 JAVA 애플리케이션에서 JPA를 사용하면 내부에서 JDBC API를 사용하여 SQL을 디비에 전달하고 결과를 반환받는다.

이를 활용하면 객체는 객체대로 정교하게 모델링을 할 수 있으며, 관계형 데이터베이스는 데이터베이스에 충실히 모델링을 할 수 있다. 또한 JPA는 인터페이스라고 하였으며 제일 많이 사용되는 하이버네이트는 대부분의 패러다임 불일치를 해결해주는 성숙한 ORM프레임워크이다.

JPA소개

기존의 EJB(엔터프라이즈 자바 빈즈)기술 표준은 엔티티 빈이라는 ORM 기술도 포함되어 있었다. 다만 너무 복잡하고 J2EE(자바 엔터프라이즈)어플리케이션 서버에만 동작하는 단점이 존재했다.

이때 가볍고 기술 성숙도가 높은 하이버네이트(Hibernate.org)라는 오픈소스 ORM프레임워크가 등장하였고, EJB3.0에서 하이버네이트를 기반으로 새로운 자바ORM기술 표준인 JPA가 탄생하였다.

JPA는 자바 ORM기술에 대한 표준 명세이다. 어떻게 사용해야 하는지 를 알려주는 인터페이스이기 때문에 JPA를 사용하기 위해 구현체를 만들어야 한다. 하이버네이트는 이를 JPA를 구현한 구현체 이다.

JPA를 사용해야 하는 이유

1. 생산성 증가

  • JPA를 사용하게 되면 반복적인 코드, CRUD용 SQL을 개발자가 직접 작성하지 않아도 된다.
  • 그냥 데이터를 컬렉션에 저장하듯 JPA에 전달하면 그 뒷내용은 JPA가 알아서 처리해준다.

2. 편리한 유지보수

  • SQL을 직접 다루면 DTO에 필드 하나만 추가하여도 관련된 등록 수정 조회 SQL결과를 매핑하는 XML등 모두 수정해야 한다.
  • JPA는 필드를 추가하기만 해도 알아서 처리해줘 코드의 양도 줄면서 시간도 단축되기 때문에 유지보수하기 용이해져 좋은 도메인 모델을 설계하기 편해진다.

3. 성능 최적화

  • 1차 캐시와 동일성을 보장한다.
  • 트랜잭션을 지원하는 쓰기 지연을 제공
  • 지연로딩과 즉시로딩

4. 하이버 네이트는 40가지 이상의 데이터베이스 방언 지원

  • 관계형 데이터베이스는 같은 기능도 디비별 사용법이 다른 경우가 많다.
  • 오라클과 MySQL은 같은 관계형 데이터베이스 이지만 쿼리문도 조금씩 다르며 사용하는 툴도 다르다.
  • 하지만 JPA는 이 모든 데이터베이스의 방언을 지원하여 특정 데이터베이스에 대한 종속에서 해방시켜준다.

출저 : https://truehong.tistory.com/99

profile
가치를 제공하는 개발자

0개의 댓글