Advance I/Springboot & JPA

22.05.26 :: 자바 ORM 표준 JPA 프로그래밍 - 기본편

kinggora 2022. 5. 28. 13:32

JPA 실무에서 어려운 이유

-처음 JPA나 스프링 데이터 JPA를 만나면? SQL 자동화, 수십줄의 코드가 한 두줄로

-실무에 바로 도입하면?

 1. 객체와 테이블을 올바르게 매핑하고 설계하는 방법을 모름

   예제들은 보통 테이블이 한 두개로 단순함

   실무는 수십 개 이상의 복잡한 객체와 테이블 사용

 2. JPA 내부 동작 방식을 이해하지 못하고 사용

    JPA가 어떤 SQL을 만들어내고, 언제 SQL을 실행하는지 이해해야 함

 

목표1. 객체와 테이블 설계 & 매핑

목표2. JPA 내부 동작 방식 이해

 

관계형 데이터베이스를 사용한다고 하면 JPA는 기본!

01. JPA 소개

SQL 중심적인 개발의 문제점

애플리케이션은 객체 지향 언어를 사용한다.

애플리케이션의 데이터 저장에 이용되는 관계형 데이터베이스는 "SQL" 만을 사용한다.

 

객체를 관계형 DB에 저장

: 객체 -(SQL 변환)-> 관계형 DB(Oracle, MySQL...)

 

객체의 필드를 추가하면 모든 SQL 쿼리에 해당 컬럼을 추가해야 한다.

결국 SQL에 의존적인 개발을 피하기 어렵다.

개발자=>SQL 매퍼

객체와 관계형 데이터베이스의 차이

상속

DB에서는 상속 관계가 없다.

  • 저장: 상속 관계를 분리하여 테이블을 설계하고, 자식 타입의 객체를 저장하려면 각 테이블에 대한 SQL 쿼리가 필요하다.
  • 조회: 각각의 테이블에 따른 조인 SQL을 작성하고 객체를 생성해서 값을 매핑해야 한다.

이 과정들이 복잡하기 때문에 RDB 에 저장할 객체에는 상속 관계 사용을 피한다.

객체 상속 관계 vs 테이블 슈퍼타입 서브타입 관계

연관관계

객체는 참조를 사용: member.getTeam()

테이블은 외래 키를 사용: JOIN ON M.TEAM_ID = T.TEAM_ID

-> 객체를 테이블에 맞추어 모델링: DB에 저장할 객체는 연관관계에 있는 객체에 대해 참조를 사용하지 않고 외래 키를 사용한다. 이는 객체지향성을 떨어뜨리는 요인이 된다.

 

객체지향성을 최대한 해치지 않게 모델링하려면 변환과정이 복잡해지고 생산성이 떨어진다.

  • 저장 예) class Member { Team team } -> member.getTeam().getId() 를 TEAM_ID 컬럼에 매핑
  • 조회 예) 데이터베이스에서 Member, Team 에 대한 정보를 각각 조회하여 객체를 생성하고 연관관계를 직접 설정해주어야 한다.

참조(단방향) vs 외래 키(양방향)

데이터 타입

데이터 식별 방법

 

객체 그래프 탐색

객체는 자유롭게 객체 그래프를 탐색할 수 있어야 한다.

 

그러나 DB에서 조회한 객체는 처음 실행하는 SQL에 따라 탐색 범위가 결정된다.

해당 객체가 참조하는 모든 객체가 조립되었는지 신뢰할 수 없다.

그렇다고 항상 모든 연관 관계를 미리 로딩할 수는 없는 일이다.

SQL에 의존적인 개발: 계층형 아키텍쳐에서 진정한 의미의 계층 분할이 어렵다. 

 

비교하기

DB에서 데이터를 조회하여 객체로 매핑하는 과정에서 조회할 때마다 매번 다른 인스턴스가 생성될 것이다.

쿼리 결과는 같을지라도 객체를 비교하면 다르다는 결과가 나온다.

정리

객체답게 모델링 할수록 매핑 작업만 늘어난다. (많은 코드)

객체를 자바 컬렉션에 저장 하듯이 DB에 저장할 수 없을까?  => JPA