본문 바로가기

Spring/JPA

(JPA) SQL 중심적인 개발의 문제점

현재는 객체를 관계형 데이터베이스에 관리해야 하는 시대이다.

관계형 데이터 베이스를 메인 디시이고 객체를 사이드디시로 생각하여 개발한다면 아래와 같은 문제점이 나타난다.

 

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

class Member {
    private final Integer memberId;
    private final String name;
    
    ...
}
INSERT INTO MEMBER (MEMBER_ID, NAME) VALUES ...

SELECT MEMBER_ID, NAME FROM MEMBER ...

 

 

memberId -> MEMBER_ID

name -> NAME

 

이러한 방식으로 개발하다 보면 칼럼이 늘어나는 경우 개발자가 칼럼 혹은 필드 값을 누락할 우려가 생긴다.

 

2. 개발자가 SQL Mapper의 역할을 한다.

 

아래 그림은 객체를 생성하고 해당 데이터를 관계형 데이터베이스를 저장하는 과정이다.

그러면 객체를 질의어로 변경하는 작업은 누가 하는 것인가?

바로 개발자가 직접 해주어야 한다. 이는 반복적인 작업을 요구하고 굉장히 많은 시간을 할애하여야 한다.

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

객체와 관계형 데이터베이스는 아래와 같은 네 가지 차이점을 가진다.

  • 상속 : 관계형 데이터베이스에는 상속관계가 없다.
  • 연관관계 : 객체는 참조값을 가지지만 관계형 데이터베이스에는 PK와 FK를 가지고 필요한 데이터를 가져온다.
  • 데이터 타입 : 객체는 VARCHAR 타입이란 존재하지 않는다.
  • 데이터 식별 방법

 

관계형 데이터베이스에는 상속관계가 없다고 하였지만 유사한 모델이 존재한다. 그것이 바로 슈퍼 타입 서브타입과의 관계이다.

 

INSERT 시

만약 부모라는 객체가 있고 그것을 상속받는 자식이라는 객체가 존재한다고 가정하자. 자바의 상속 특성상 자식은 부모의 모든 레퍼런스를 사용할 수 있다.

하나 관계형 데이터베이스에서는 자식에 대한 값을 넣을 때 그것을 참조하는 부모의 값 또한 생성을 해주어야 한다.

 

SELECT 시

자식에 대한 값을 가져올 때 부모와 함께 JOIN 하여 가져오는 작업이 필요하다.


연관관계를 객체지향적으로 디자인한다면?

class Member {
    private final Integer id;
    private final Team team; //객체의 참조값
    private final String userName;
}

 

private final Team team; 이 부분을 DB에 어떻게 넣을 것인가?

getter를 사용해서 해당 값을 불러올 수 있지만 값을 select 할 때는 Member와 Team에 대한 값을 분리해서 일일이 넣어주어야 한다.

 

 

엔티티의 신뢰성 문제

 

class MemberService {
    
    public void process() {
        Member member = memberDAO.find(memberId);
        
        // 호출할 수 있을까?
        member.getTeam();
        member.getDelivery().getOrder();
    }
}

 

 

위의 코드에서 과연 member.getTeam();, member.getDelivery(). getOrder();을

알 수가 없다.

 

find 시에 찾아온 결괏값을 기준으로 이미 결정이 나기 때문에 쿼리를 일일이 확인하기 전까지는 알 수가 없다. 그렇기 때문에 신뢰할 수 없다.

 

 

비교

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

member1= member2;
public Member getMember(Integer memberId) {
    String sql = "SELECT * FROM ...";

    return new Member(...);
}

member1이 member2랑 당연히 새로운 인스턴스를 생성해서 반환하였기 때문에 다르다.

 

하나 리스트 컬렉션이라고 가정하자면 같은 id를 찾을 때는 참조값이 갚기 때문에 TRUE를 반환한다.


결론

객체답게 모델링할수록 관계형 데이터베이스와 객체 간의 매핑하는 작업만 늘어난다.

이에 따라 객체를 자바 컬렉션에 저장하듯이 데이터베이스에 저장할 수 없을까라는 고민에서 나온 것이 JPA이다.


References

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

 

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

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

www.inflearn.com