본문 바로가기
JPA

[JPA] JPA 소개(1) - SQL 중심적인 개발의 문제점

by 개발현욱 2023. 1. 31.

SQL 중심적인 개발의 문제점

SQL 의존

주로 관계형 DB를 사용 → 객체를 관계형 DB에 저장 → 수많은 SQL 사용 (CRUD, 무한반복, 지루) → SQL에 의존적

패러다임 불일치

  • 객체 현실적으로는 관계형 데이터베이스
  • 객체 -> SQL 변환 -> RDBMS

-> 개발자가 함

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

  1. 상속
  • 추상화 → 객체 상속

  • 관계형 데이터베이스 테이블 (상속 관계 X)

    • 부모 테이블, 자식 테이블 조인 → 슈퍼타입, 서브타입 관계

    • CRUD

      • C : 객체 분해, INSERT INTO ITM…, INSERT INTO ALBUM ..

      • R

        • 테이블 조인
        • 객체 생성 …
      • 각각 서브타입 케이스마다 조인 쿼리문 작성 필요 (개발자가 한다)

        → 자바 컬렉션에서

      • C : add해주면 됨

      • R : get 해주면 됨 (부모타입은 다형성 이용)

  1. 연관관계
  • 객체는 참조를 사용

  • 테이블은 외래키를 사용 (조인)

  • 객체를 테이블에 맞추어 모델링

    • 등록

        class Member {
            String id;
            Long teamId; // TEAM_ID FK
            String username;
        }
      
        class Team {
            Long id; // TEAM_ID PK
            String name;
        }

      → 객체 다운 모델링이 아니다 (객체는 참조로 연관간계를 성립하기 때문)

        class Member{
            String id;
            Team team; // 참조로 연관관계를 맺는다
            String username;
        }
      
        class Team {
            Long id; // TEAM_ID PK
            String name;
        }

      → 문제점 : 데이터베이스에 INSERT 하기가 까다로움

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

      → TEAM_ID를 불러오기 위해서는 member.getTeam().getId();

    • 조회

        SELECT M.*, T.* FROM MEMBER M
        JOIN TEAM T ON M.TEAM ID = T. TEAM ID
        public Member find (String memberId) {
        //SQL 실행...
        Member member = new Member ( );
        //데이터베이스에서 조회한 회원 관련 정보를 모두 입력
        Team team = new Team ( ) ;
        //데이터베이스에서 조회한 팀 관련 정보를 모두 입력
      
        //회원과 팀 관계 설정
        member.setTeam(team); //** 
        return member;
        }
  • 객체 모델링을 자바 컬렉션에서 관리

    • 등록

        list.add(member);
        Member member = list.get(memberId);
        Team team = member.getTeam();
  • 객체 그래프 탐색

    • 객체는 자유롭게 객체 그래프 탐색을 할 수 있어야 한다. (참조로 각 객체들을 따라갈 수 있어야 한다.)

    • 처음에 어떤 SQL로 객체를 생성하냐에 따라서 탐색 범위가 결정돼버림.

        // MEMBER와 TEAM을 조인
        SELECT M.*, T.* FROM MEMBER M
        JOIN TEAM T ON M.TEAM ID = T. TEAM ID
        member. getTeam ( ); //OK 
        member.getOrder () ; //null

      → Entity 신뢰 문제

      → 그렇다고 모든 객체를 로딩해놓을 순 없다.

  • 비교하기

      String memberId = "100";
      Member member1 = memberDAO.getMember(memberId) ;
      Member member2 = memberDAO.getMember(memberId) ;
    
      member1 == member2;//다르다.
      //이유 : 각 SQL 결과물을 각각 새로운 객체 인스턴스를 생성해서 반환하기 때문
    
      class MemberDAO {
          public Member getMember (String memberId) {
              String sq1 = "SELECT * FROM MEMBER WHERE MEMBER ID = ?";
              ...
              //JDBC API, SQL 실행
              return new Member ( ... );
          }
      }
  • 비교하기 - 자바 컬렉션에서

      String memberId = "100";
      Member member1 = list.get(memberId);
      Member member2 = list.get(memberId);
    
      member1 == member2 // 같다.
      //이유 : 컬렉션에서 같은 인스턴스를 조회하면 같은 참조임.
  1. 데이터 타입

  2. 데이터 식별 방법

결론 : 객체답게 모델링 할수록 매핑 작업만 늘어난다.

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

JPA 탄생

728x90
반응형