Lined Notebook

[Spring Data JPA] 03. SQL 중심 개발의 문제점

by ymkim

✔ SQL 중심적인 개발의 문제점

SQL을 작성해서 개발을 진행?

CRUD
INSERT INTO...
UPDATE...
SELECT...
DELETE...
자바 객체를 SQL로 표현...
SQL을 자바 객체로...
  • 무한반복, 지루한 코드
  • 결국은 개발자가 SQL을 다 작성해야 한다

객체 CRUD

public class Member {
    private String memberId;
    private String name;

    ..
}

INSERT INTO MEMBER(MEMBER_ID, NAME) VALUES
SELECT MEMBER_ID, NAME FROM MEMBER M
UPDATE MEMBER SET ...
  • 회원 테이블 생성 후, 회원 객체를 생성한다
  • 기본 SQL 작업을 수행한다
  • 기획자가 갑자기 요구사항을 변경한다
  • 변경 되어야 하는 부분 - DB, 객체(Member)

SQL 의존적인 개발

  • RDBMS를 사용하게 되면 SQL에 의존적인 개발을 피하기가 힘들다

Mybatis

  • JDBC를 대체하는 퍼시스턴스 프레임워크로 기존 JDBC가 제공하던 불편한 부분을 보완해 나온 기술
  • 개발자가 직접 SQL을 작성하여 세부적인 쿼리 조작이 가능하며, 비즈니스 로직과 SQL을 분리하여 레이어 구분이 가능

객체 vs 관계형 데이터베이스

  • 패러다임의 불일치?
  • 객체 지향이 나온 사상과, 관계형 데이터베이스가 나온 사상이 다르다
  • 관계형 DB는 데이터를 잘 정규화하여 보관하는 목적
  • 객체지향은 속성기능잘 캡슐화하여 쓰는 목적
    • 객체 지향 프로그래밍은 추상화, 캡슐화, 정보은닉, 상속, 다형성 등
    • 시스템의 복잡성을 제어할 수 있는 다양한 장치들을 제공한다

현실적인 대안은 관계형 DB?

  • 객체 -> SQL 변환 -> SQL RDB
  • 개발자 == SQL 매퍼 ( Mybatis, ibatis )
  • 즉, 이말은 개발자가 관여해야하는 부분이 많아진다는 의미
  • SQL을 반복적으로 직접 작성하여 RDB와의 데이터 수/송신을 해야함

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

상속

  • 객체
    • 객체에는 상속 관계가 존재
  • DB
    • DB에는 상속 관계가 존재하지 않음, 굳이 정의 하자면 Super type, Sub Type

연관관계

  • 객체
    • 객체에는 연관관계가 존재 ( 연관 객체를 참조하여 가져온다 )
  • DB
    • DB에는 PK, FK를 통해 데이터 조인
  • 데이터타입
  • 데이터 식별 방법

자바 컬렉션에 저장?

Album album = list.get(albumId);
Item item = list.get(albumId);
  • 만약 자바 컬렉션에 저장을 한다고 하면, 해당 컬렉션에 넣었다, 뺏다만 해주면 된다
  • 또한 다형성을 이용하여 부모 타입으로 자식 타입의 객체를 받을 수 있다
  • 관계형 DB 사용 시 개발자가 SQL을 작성해서 모든 부분을 관리

연관관계

--------------------------------------------------
객체
Member                          Team
id                              id
Team team           ->          name
userName

테이블
MEMBER                          TEAM
MEMEBER_ID (PK)                 TEAM_ID (PK)
TEAMP_ID (FK)                   NAME
USERNAME
--------------------------------------------------
  • 객체는 참조를 사용
    • member.getTeam();
  • 테이블은 외래키를 사용
    • JOIN IN M.TEAM_ID = T.TEAM_ID
    • Member 객체 -> Team 객체 ( o )
    • Team 객체 -> Member 객체 ( x )
    • MEMBER 테이블 -> TEAM 테이블 ( o )
    • TEAM 테이블 -> MEMBER 테이블 ( o )
  • 객체는 단방향, 테이블을 양방향

객체 모델링, 자바 컬렉션에 관리?

list.add(member);

Member member = list.get(memberId);
Team team = member.getTeam();
  • 추상화
    • SuperMember > Member > Team

객체 그래프 탐색

SELECT M.*, T.*
FROM MEMBER M
JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
  • 객체는 자유롭게 객체 그래프를 탐색할 수 있어야 한다 ( 메서드 체이닝 )
  • 처음 실행하는 SQL에 따라 탐색 범위가 결정됨
    • 즉, 이 말은 MEMBER랑 TEAM 테이블만 조인을 하였기에 범위가 2개로 좁혀진다
    • ORDER 테이블에서 데이터를 가져오려면 조인을 또 추가해야 한다

객체 그래프 탐색 - 엔티티 신뢰 문제

class MemberService {
    ...
    public void process() {
        Member member = memberDao.find(memberId);
        member.getTeam();
        member.getOrder().getDelivery();
    }
}
  • memberDao에서 member객체를 반환해주네?
  • Team, order객체를 반환 받아볼까?
  • memberDao에 맵핑된 쿼리를 직접 보지 않는 이상 신뢰할 수없다
  • Layered architecture 각 계층의 신뢰성이 보장 되어야 한다
    • 하지만 현재는 DAO에서 어떤 행동(Action)을 했는지 일일이 까봐야 알 수 있음

엔티티 신뢰를 지키기 위한 방법

memberDao.getMember();

memberDao.getMemberWithTeam();

//Member, Order, Delivery
memberDao.getMemberWithOrderWithDelivery();
  • 테이블마다 가져오고자 하는 값을 분리하여, 데이터를 가져온다
  • 대부분 이런 방식으로 구분을 하여 데이터를 가져옴
  • 실무에서도 결제 문서를 가져오는 SQL, 유저 정보를 가져오는 SQL을 각각 짜서 사용한다

계층형 아키텍처

  • SQL을 통한 구현은 진정한 의미의 계층 분할( Layerd Arcitecture )가 어렵다.

비교하기

String memberId = "100";
Member member1 = memberDao.getMember(memberId);
Member member2 = memberDao.getMember(memberId);

member1 == member2; // 두 객체는 다르다

class MemberDao {

    public Member getMember(String memberId) {
        String sql = "SELECT * FROM MEMBER WHERE MEMBER_ID = ?";
        ...
        // JDBC API, SQL 실행
        return new Member(...);
    }
}
  • memeberId가 100인 데이터를 넣어서 member1, member2 객체를 반환 받는다
  • 하지만 결과는 false가 나온다, 객체가 참조하고 있는 주소가 다르기 때문이다
  • 이러한 부분을 통해 객체의 일관성이 보장되지 않음을 알 수 있다

비교하기 - 자바 컬렉션에서 조회

String memberId = "100";
Member member1 = list.get(memberId);
Member member2 = list.get(memberId);

member1 == member2;
  • 참조값이 동일하게 나온다

문제점을 해결하기 위한 해결 방안

  • 🚀 객체 지향적으로 설계를 하고 모델링을 할수록 매핑 작업이 늘어난다
  • 🚀 객체를 자바 컬렉션에 저장 하듯이, DB에 저장할 수 없을까?
    • 📌 이러한 고민의 결과가 JPA - Java Persistance API다

참고 자료

블로그의 정보

기록하고, 복기하고

ymkim

활동하기