탱구탱구 개발자 일기

1. ORM 등장 배경

 

자바 웹 애플리케이션 개발 = JAVA + RDBMS(관계형 데이터베이스)

 

초기 : 개발 단계에서 JDBC API + SQL에 많은 시간 할당, 운영단계에서 업무의 시작과 끝을 SQL과 함께...

 

과도기: iBatis나 MyBatis, Spring JDBC Template 같은 SQL Mapper의 탄생으로 JDBC API 및 SQL 작성 시간이 줄어듦

 

하지만 지루한 CRUD SQL을 반복하고 SQL 중심적으로 개발하는 것을 막을 수 없었다.

즉 객체 모델링이 아닌 RDBMS에 맞게 데이터 중심으로 테이블 설계 작업이 중시되었다.

또한, 말이 객체지향적 프로그래밍이지 객체는 단순히 RDBMS로 옮기기 전 그릇에 불과했다.

마지막으로 비즈니스 로직 변경에 따른 SQL 수정이 항상 동반되었다.

 

ORM(Object-Relational Mapping) 기술의 등장

  • 객체는 객체대로 설계 => ex) SQL 중심이 아닌 Java 코드에 맞게 설계
  • RDBMS는 RDBMS대로 설계
  • ORM 프레임워크가 객체와 테이블을 매핑시켜줌
  • Java에만 국한된 것이 아니라 대중적인 프로그래밍 언어들에는 ORM 프레임워크가 존재

 

2. JPA란?

  • Java ORM 기술에 대한 API 표준 명세
  • Java로 개발된 응용프로그램에서 RDBMS의 관리를 표현 => Application과 JDBC 중간에 위치
  • 즉 객체를 테이블과 매핑시켜줌

JPA 동작 원리

 

패러다임의 불일치

  • 프로그래밍 언어와 RDBMS 구조 및 특성이 다름
  • 객체에는 상속이 있지만 테이블에는 상속 개념이 없다
  • 객체에선 참조를 통해 다른 객체에 접근해 연관 객체를 찾지만 테이블은 FK(외래 키) 사용하여 다른 테이블과 조인을 통해 탐색한다.
  • 객체 그래프 탐색 문제

[객체 연관관계]

  • Item 객체는 Book 객체를 getBook 메서드를 통해 접근 가능
  • 그러나 Book 객체에선 Item
public class Item {

    Long id; //Item_id PK사용
   
    Book book; //참조로 연관관계 설정!
    
    public Book getBook() {
        return book;
    }
    
    public Item createItem(Book book) {
        Item item = new Item();
        item.getBook(); // book 참조변수를 통해 Item에서 Book객체에 접근 가능
        return item;
    }
}

public class Book {

   Long id; //Book_id PK 사용
   String name; //Name 컬럼 사용
    
   public Book createBook() {
       Book book = new Book();
       book.getItem(); // Error : Book에서 Item을 접근할 수 있는 참조변수가 존재하지 않음
       return book;
   }
}

 

[테이블 연관관계]

  • SQL을 통해 두 테이블 JOIN이 가능하도록 객체를 설계해야 함
  • ITEM 객체에서 BOOK 객체로 바로 접근이 불가하고 SQL에서 두 테이블을 FK로 조인해야 함! 
public class Item {

    String id; //Item_id PK 사용
    Long bookId; //Book_id FK 사용
}

public class Book {

    Long id; //Book_id PK 사용
    String name; //name 컬럼 사용
}

 

ITEM 테이블과 BOOK 테이블 관계

 

[객체 그래프 탐색 문제]

  • SQL을 직접 다루면 모든 객체를 조회할 수 있는 것이 아니라 SQL 코드에 따라 객체 그래프가 달라짐
  • 참조를 통한 연관관계를 설정하면 필요한 연관 객체까지 자유롭게 탐색 가능함
  • 연관되었다고 해당 연관 객체를 DB에서 select 하는 것이 아니라 해당 객체를 사용하는 시점에 select문이 호출된다 => 지연 로딩(LAZY)

3. 정리

 

객체지향적 언어가 발전하면서 좀 더 객체 중심의 프로그래밍이 가능해졌지만 결국 DATA는 RDBMS를 통해 저장되기 때문에 애플리케이션이 복잡해지고 고도화될수록 객체끼리 접근이 많아지고 그렇게 되면 객체 모델링 시 패러다임의 불일치가 커진다. 그래서 개발자는 점차 다시 데이터 중심 모델링으로 바꾸게 되는 경향이 크다.

 

JPA는 이러한 패러 다임의 불일치 문제를 고민해 해결하면서 정교한 객체 모델링을 유지하게 도와준다. 이는 즉 개발자의 생산성을 높게 된다. 그러나 아직까지 통계성 쿼리 등 복잡한 SQL에는 JPA만으로 힘든 점이 있다. 그래서 이를 보완하기 위해 QueryDSL 라이브러리 등을 통해 보완하고 있다.

 

 

이 글을 공유합시다

facebook twitter kakaoTalk kakaostory naver band
loading