[Spring]/JPA 프로그래밍 - 기본편

SQL 중심적인 개발의 문제점

응파카 2023. 3. 27. 13:15
  • 객체를 RDB에 저장하고 관리하는 요즘
  • 이를 보관하고 관리하기 위해서는 SQL을 알아야 한다.

무한반복, 지루한 코드..

자바 객체를 SQL로 바꾸고 SQL을 자바 객체로 바꾸고를 무한 반복

새로운 필드를 추가하는 등 변경사항이 생기면 또 쿼리문을 다 고쳐야 함

즉, SQL에 의존하는 개발을 할 수 밖에 없게 된다.

 


패러다임의 불일치

객체와 RDB의 테이블이 완전히 일치하지 않는다.

객체를 RDB에 저장하려면

  • 객체데이터를 SQL로 바꾼다
  • SQL로 RDB에 전달한다

이 과정을 개발자가 한다. (SQL mapper)

객체와 RDB의 차이 4가지

  1. 상속
  2. 연관관계
  3. 데이터 타입
  4. 데이터 식별방법

 


상속

Item 클래스를 상속받는 Album 클래스가 있다고 가정하자.

  • 객체에는 상속관계가 있다.
  • DB 테이블에는 상속이라는 관계가 없다.
    • Table 슈퍼타입 서브타입 관계로 구현은 가능하지만,
    • 저장 → 쿼리의 수가 늘어남 (객체 분해로 인해 Item과 Album 테이블 전부에 INSERT 해줘야 함)
    • 조회 → Album를 조회하는 경우 Item과 Album 테이블에 따른 JOIN SQL을 작성해야 한다. 이후 각각의 객체를 생성해야 한다. 또 해당 데이터를 전부 세팅하고…

이 복잡한 과정을 개발자가 다 해야한다.

위와같은 이유로 DB저장에는 Table 슈퍼타입 서브타입 관계를 사용하지 않는다.

  • 반면 자바 Colllection에 저장하는 경우
list.add(bmw); //저장

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

Item item = list.get(albumId); (부모 타입으로 조회 후 다형성 활용) //조회

 


연관관계

  • 객체는 참조를 사용한다.
  • 테이블은 외래 키를 사용한다.

Member와 Team 객체가 있다고 할 때, 원래는 객체를 테이블 형식에 맞춰서 모델링 해야 한다.

Member 내에 Team 필드가 있는것이 아니라, Long teamId (외래키 컬럼) 필드를 갖는다.

INSERT INTO MEMBER ( MEMBER_ID, TEAM_ID, USERNAME ) VALUES …

하지만 객체다운 객체는 참조로 연관관계를 맺는다.

Member 안에 Long teamId 대신 Team 필드를 갖는다고 하면 TEAM_ID를 따로 뽑아줘야 한다.

member.getTeam().getId();

조회를 위해서는 Member와 Team을 한 번에 JOIN 한다.

이후 Member와 Team 객체를 각각 만들어 데이터 세팅 하고

Member와 Team의 관계를 세팅해줘야 한다.

자바 Collection의 경우

list.add(member);

Member member = list.get(memberId);

Team team = member.getTeam();

하면 끝난다.

 


객체 그래프

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

처음 실행하는 SQL (SELECT …..) 에 따라서 탐색 범위의 한계가 결정된다.

이는 계층형 아키텍쳐에서의 Entity 신뢰 문제와 직결된다.

즉, 서비스 로직을 짜는데 DAO를 전부 분석해야 어디까지 조회 가능한지 등을 알 수 있다.

조회하는 경우 분석하지 않고 사용 가능하게 하기 위해서는 상황에 따라 동일한 조회 메서드를 줄줄이 만들어야 한다..

예를 들면 다음과 같이

memberDAO.getMember();
memberDAO.getMemberWithTeam();
memberDAO.getMemberWithTeamwithOrderWithDelivery();
...

즉, 진정한 의미의 계층 분할이 어렵다.

물리적으로는 분할되어 있지만 논리적으로는 분할되어있지 않다.

 


비교하기

Long memberId = 100;

Member member1 = memberDAO.getMember(memberId);
Member member2 = memberDAO.getMember(memberId);

라고 할 때,

member1 == member2;
  • SQL 쿼리 짜고, 데이터를 넣은 새로운 객체를 만들어서 안에 SQL 쿼리 결과를 넣어서 반환하기 때문에, 새로운 인스턴스 두 가지가 생겨난다. (데이터는 동일) 두 인스턴스는 다르다.
  • 이를 자바 Collection에서 조회 한다면, 두 인스턴스는 같게 나온다. Collection 에서 같은 인스턴스를 참조 하기 때문이다.

 

 


 

https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com

 

'[Spring] > JPA 프로그래밍 - 기본편' 카테고리의 다른 글

영속성 컨텍스트 1  (0) 2023.04.07
Hello JPA - 애플리케이션 개발  (0) 2023.03.28
Hello JPA - 프로젝트 생성  (0) 2023.03.27
JPA 소개  (0) 2023.03.27
강좌 소개  (0) 2023.03.27