Spring/Spring Data JPA

[Spring Data JPA] 2. ORM 이란? & 패러다임 불일치

미스터로즈 2021. 8. 7. 15:55

백기선님 강의 중 Spring Data JPA에 대해서 정리를 해놓은 블로그입니다.

자세한 내용은 강의를 참고해주세요.

강의 링크


 

이전 강의에서 진행했던 방식 -> JDBC 방식

 try(Connection connection = DriverManager.getConnection(url,username,password)){
         System.out.println("Connection created: "+connection);
         String sql = "INSERT INTO ACCOUNT VALUES(1,'hyeon','pass')";
         try(PreparedStatement statement = connection.prepareStatement(sql)){
             statement.execute();
         }
   }

 

도메인 모델 사용

Account account = new Account(“keesun”, “pass”);
accountRepository.save(account);

JDBC 대신 도메인 모델 사용하려는 이유?

  • 객체 지향 프로그래밍의 장점을 활용하기 좋습니다.
  • 각종 디자인 패턴 활용할 수 있습니다.
  • 코드 재사용성이 좋습니다.
  • 비즈니스 로직 구현 및 테스트 편합니다.

 

 

 


ORM 이란?

ORM은 Object-Relation Mapping의 약자로,

애플리케이션의 클래스와 SQL 데이터베이스의 테이블 사이의 맵핑 정보를 기술한 메타데이터를 사용하여, 자바 애플리케이션의 객체를 SQL 데이터베이스의 테이블에 자동으로 영속화 해주는 기술입니다.

 

맵핑 정보를 기술한 메타데이터

어떠한 도메인 모델에 있는 어떠한 멤버 변수가 어떠한 테이블의 컬럼과 Mapping이 되는 가를 제공을 해줘야 합니다.

또는 어떤 클래스가 어떤 테이블과 매핑을 할것인지....

 

이러한 정보를 기반으로 자바의 객체를 SQL 데이터베이스 테이블에 자동으로 매핑을 해줍니다.

 

 

 

장 단점

장점

  • 생산성
    쉽고 빠르게 매핑 정보만 정의만 하면 데이터를 다루는게 빠릅니다.
  • 유지보수성
    코드가 간결. 코드에 로직만 보이게 됩니다.
  • 성능
    하이버네이트가 만드는 쿼리문이 우리가 직접 작성한 쿼리보다 느릴 수 있음. 하지만 하이버네이트에서는 성능 최적화를 위한 여러가지 기능을 제공함. 예를 들어, 캐시가 있음. 불필요한 쿼리를 매번 사용해 데이터를 불러내지 않고 한 번 불러낸 데이터를 캐시에 저장해 이후에 데이터가 필요할 때 캐시에 저장된 데이터를 내보내기 때문에 빠름.
  • 벤더 독립성
    SQL을 작성할 때는 어떤 데이터베이스에 작성할 것인지를 염두해야 합니다. 이는 벤더마다 SQL문이 조금씩 다르기 때문입니다. 하지만 하이버네이트를 사용하면 Dialect(사용하고자 하는 데이터베이스)만 설정해 주면 그에 맞는 SQL문을 생성하게 됩니다. 데이터베이스를 바꾸더라도 우리의 코드는 바뀌지 않습니다.

단점

  • 학습비용
    SQL문 공부하는 것도 포함. 하이버네이트가 SQL문을 자동으로 생성해준다고 해서 쿼리를 몰라도 되는 것은 아님. 하이버네이트를 더 잘 사용하기 위해서는 SQL을 공부해야함. 하이버네이트는 만만한 프레임워크가 아님. 그럼에도 불구하고 엄청난 장점이 있기 때문에 학습하는 것이 좋음. 하이버네이트 때문에 성능이 나빠졌다는 소리를 하는 사람은 학습이 부족한 것.

패러다임 불일치

객체를 릴레이션에 맵핑하려니 발생하는 문제들과 해결책

 

밀도(Granularity) 문제

객체 릴레이션
다양한 크기의 객체를 만들 수 있음.
커스텀한 타입 만들기 쉬움.
테이블
기본 데이터 타입 (UDT는 비추)

 

서브타입(Subtype) 문제 

객체 릴레이션
상속 구조 만들기 쉬움.
다형성.
테이블 상속이라는게 없음.
상속 기능을 구현했다 하더라도 표준 기술이 아님.
다형적인 관계를 표현할 방법이 없음.

 

식별성(Identity) 문제

객체 릴레이션
레퍼런스 동일성 (==)
인스턴스 동일성 (equals() 메소드)
주키 (primary key)

 

관계(Association) 문제

객체 릴레이션
객체 레퍼런스로 관계 표현.
근본적으로 ‘방향'이 존재 한다.
다대다 관계를 가질 수 있음
외래키(foreign key)로 관계 표현.
‘방향'이라는 의미가 없음. 그냥 Join으로 아무거나 묶을 수 있음.
태생적으로 다대다 관계를 못만들고, 조인 테이블 또는 링크 테이블을 사용해서 두개의 1대다 관계로 풀어야 함.

 

데이터 네비게이션(Navigation)의 문제 

객체 릴레이션
레퍼런스를 이용해서 다른 객체로 이동 가능.
콜렉션을 순회할 수도 있음.
하지만 그런 방식은 릴레이션에서 데이터를 조회하는데 있어서 매우 비효율적이다.
데이터베이스에 요청을 적게 할 수록 성능이 좋다. 따라서 Join을 쓴다.
하지만, 너무 많이 한번에 가져오려고 해도 문제다.
그렇다고 lazy loading을 하자니 그것도 문제다. (n+1 select)