목차
JPA 개요
JPA는 Java Persistence API의 줄임말입니다. JPA는 자바 진영에 ORM(Object-Relational Mapping) 기술 표준으로 사용되는 인터페이스의 모음 입니다. 인터페이스의 모음이라 실제적으로 구현된 것이 아니라 구현된 클래스와 매핑을 해주기 위해 사용되는 프레임워크입니다. JPA를 구현한 대표적인 오픈소스로는 Hibernate가 있습니다.
ORM 개요
ORM은 Object Relational Mapping의 줄임말입니다. 애플리케이션 Class와 RDB(Relational DataBase)의 테이블을 매핑(연결)한다는 뜻으로 기술적으로는 애플리케이션의 객체를 RDB 테이블에 자동으로 영속화를 해줍니다.
장점
- SQL문이 아닌 Method를 통해 DB를 조작할 수 있어, 개발자는 객체 모델을 이용하여 비즈니스 로직을 구성하는데 집중 할 수 있습니다. (내부적으로는 쿼리를 생성하여 DB를 조작합니다. 하지만 개발자는 이를 신경쓰지 않아도 됩니다.)
- Query와 같이 필요한 선언문, 할당 등의 부수적인 코드가 줄어들어, 각종 객체에 대한 코드를 별도로 작성하여 코드의 가독성을 높입니다.
- 객체지향적인 코드 작성이 가능합니다. 오직 객체지향적 접근만 고려하면 되기 때문에 생상선이 증가합니다.
- 매핑하는 정보가 Class로 명시되었기 때문에 ERD를 보는 의존도를 낮출 수 있고 유지보수 및 리팩토리에 유리합니다.
- 예를 들어 기존 방식이 MySQL 데이터베이스를 사용ㅇ하다가 PostgreSQL로 변환되었다고 하면 새로 쿼리를 짜야하는 경우가 생기는데 ORM을 사용한다면 쿼리를 수정할 필요가 없습니다.
단점
- 프로젝트 규모가 크고 복잡하여 설계가 잘못된 경우, 속도 저하 및 일관성을 무너뜨릴 수 있습니다.
- 복잡하고 무거운 Query는 속도를 위해 별도의 튜닝이 필요하기 때문에 결국 SQL문을 써야할 수도 있습니다.
- 학습비용이 비쌉니다.
JPA
- Java 진영에서 ORM 기술 표준으로 사용하는 인터페이스 모음
- 자바 애플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스
- 인터페이스이기 때문에 Hibernate, OpenJPA 등의 구현체를 사용합니다.
JPA를 사용하는 이유
JPA는 반복적인 CRUD SQL을 처리해줍니다. JPA는 매핑된 관계를 이용해 SQL을 생성하고 실행하는데 개발자는 어떤 SQL이 실행되지 생각할 수 있고 쉽게 예측할 수 있습니다. JPA는 네이티브 SQL이란 기능을 제공하는데 관계 매핑이 어렵거나 성능에 대한 이슈가 우려되는 경우 SQL을 직접 작성하여 사용할 수 있습니다.
JPA를 사용하여 얻는 가장 큰 이득은 SQL이 아닌 객체 중심인 개발을 할 수 있다는 것 입니다. 이에 따라 생산성도 좋아지고 유지보수도 수월해 집니다. 또한 JPA는 패러다임의 불일치도 해결해 줍니다. 예를 들어 JAVA에서 부모클래스와 자식클래스의 관계인 상속관계가 존재하는데 데이터베이스에는 이러한 객체의 상속관계를 지원하지 않습니다. 이런 상속관계를 JPA는 다음과 같은 방식으로 해결합니다.
위의 구조에서 자식 클래스인 Album 클래스를 저장한다고 가정해 봅니다.
jpa.persist(album);
그러면 JPA는 위의 코드를 다음의 쿼리로 변환해 실행합니다.
INSERT INTO ITEM(ID, NAME, PRICE)...
INSERT INTO ALBUM(ARTIST)...
조회할 때도 두 테이블을 엮어서 가저옵니다.
String albumId = "id001";
Album album = jpa.find(Album.class, albumId);
// 변환된 쿼리
SELECT I.*, A.*
FROM ITEM I
JOIN ALBUM A ON I.ITEM_ID = A.ITEM_ID
위와 같이 상속관계에 대한 접근을 제공합니다. 또한 객체지향에는 연관관계 라는 것도 있습니다.
코드로 보면 Class에서 또 다른 Class Type을 필드 변수로 가지고 있는 것 입니다.
위의 그림은 Member 클래스가 Team 타입의 team 필드 변수를 가지고 있는 형태입니다.
Class Member {
String id;
Team team;
String username;
}
class Team {
Long id;
String name;
}
Member 객체의 저장
Member member = new Member();
member.setId("10");
member.setUsername("dbjh");
Team team new Team();
team.setName("dev_team");
member.setTeam(team);
jpa.persist(member);
Member 객체의 team 필드에 Team 객체를 set하고 Member 객체를 DB에 저장하게 되면 JPA는 아래와 같은 코드를 데이터베이스에 전송합니다.
INSERT INTO MEMBER(ID, TEAM_ID, USERNAME) ...
INSERT INTO TEAM(ID, NAME)...
저장 후 Member 객체만 조회하면, Team 객체 정보도 가져와서 Member 객체의 team 필드에 주입해줍니다.
// Java 코드
Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam();
// 변환된 쿼리
SELECT M.*, T.* FROM MEMBER M JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
위와 같이 구조물들이 복잡해져도 JPA는 이를 모두 지원해주기 때문에 문저없이 사용할 수 있습니다. 위에서 다룬 JPA의 저장 및 조회는 아래와 같이 실행됩니다.
저장
조회
참고로 JPA는 수정 메소드를 제공하지 않습니다. 하지만 당연히 수정은 필요하기 때문에 JPA는 데이터 수정시, 매핑된 객체(테이블 데이터)를 조회해서 값을 변경 후 커밋하면 DB 서버에 UPDATE 문을 전송하여 UPDATE를 실행합니다.(변경감지)
참조
[Spring JPA] JPA 란?
이번 글에서는 JPA(Java Persistence API)가 무엇인지 알아보려고한다. JPA는 자바 진영에서 ORM(Object-Relational Mapping) 기술 표준으로 사용되는 인터페이스의 모음이다. 그 말은 즉, 실제적으로 구현된것이
dbjh.tistory.com