[Java] ORM에 대한 고찰

ORM vs SQL Mapper

자바를 이용해 API 를 개발하다 보니, 뭐가 더 효율적인 방법인지 호기심이 생겼고 개인적으로 와닿는 부분을 커뮤니티 ‘OKKY’ 에서 가져 온 내용입니다.

해당 내용은 한번쯤 읽기 좋은 내용이라고 생각되니 시간이 된다면 읽이보는걸 추천합니다.
ORM 이냐 SQL Mapper(MyBatis) 냐 를 두고 개발자들끼리의 토론인데, 대결구도 인 만큼 글도 잘 읽히고 흥미로워요. 개인적으로 인상적인 댓글만 몇개 떠왔습니다.

댓글에 언급한들은 제 경력과 수준으로 비빌수도 없겠지만, 가독성 있고 이해하기 쉽게 적어주셔서 모두 읽기에 부담이 없다고 생각됩니다.

각 진영의 주장을 요약하자면 이렇습니다.

SQL Mapper 진영의 주장

  • ORM 은 대세가 아니다.
  • ORM 은 SQL Mapper 에 비해 가독성이 떨어지고 인수인계가 어렵다. (모르는 사람이 많기 떄문에)

ORM 진영의 주장

  • ORM 은 대세가 맞다.
  • ORM 은 생산성이 높다.

공통 된 주장

  • ORM 은 러닝커브가 높다.
  • ORM 은 한계가 있다. (복잡한 통계 쿼리 등)
  • ORM 의 의미를 찾으려면 탑다운(Top-down) 방식으로 설계를 해야하지만, 한국에서는 바텀업(bottom-up) 방식의 개발이 많다.
  • 객체지향적인 부분에서는 ORM 이 객체지향적이다.
  • 대한민국의 현실에서는 SQL Mapper 를 사용하게 된다.


보통 소프트웨어 개발 단계는 요구사항 분석 – 설계 – 구현 – 테스팅 – 유지보수의 주기를 가지고 있다.
탑다운 방식은 전체를 분석하고 설계하는데 시간을 많이 들이는 방식이고
바텁업 방식은 작은 것부터 하나씩 구현해서 전체를 만드는 방식이다.


Okky 의 내용

  • Atlassian, AT&T, Cisco, 쿠팡 등의 매출이 큰 기업에서도 ORM을 채택해서 사용하며, 현재 국내 구직시장을 보더라도 ORM 에 대한 경험자를 원하는 곳이 많다.
  • 전자정부 표준 프레임워크에도 ORM 프레임워크인 JPA가 표준 기술로 포함되어 있다.
  • 구글 트렌드 검색
    • JPA, Hibernate는 94%
    • iBatis, myBatis는 6%
  • ZeroTurnaround 전세계 자바 개발자 대상 통계
    • 하이버네이트(JPA 구현체): 67.5%
    • 순수 JDBC: 22%
    • SpringJdbcTemplate: 19.5%
    • EclipseLink(JPA 구현체): 13%
    • MyBatis: 6.5%
    • JOOQ:  1.5%

핵심은 데이터다.

차세대에서 운영체제나 언어가 바뀌는 경우는 있어도 데이터 구조가 크게 바뀌는 경우는 거의 없다고 봐도 됩니다. 결국 가장 핵심이 데이터라고 봐도 무방합니다 자바, C, 파이썬 같은 언어는 물론이고, JPA, Hibernate 같은 ORM 프레임워크들도 시간이 지나면 사라지겠지요. 하지만 데이터는 적어도 그 것을 운영하는 회사가 사라지기 전까지는 남아있겠지요. JPA나 하이버네이트를 많이 다루어본 개발자분들도 항상 강조하는 것이 데이터입니다. ORM은 이름 그대로 객체(O) 관계형 데이터베이스(R)을 중간에서 매핑(M)하는 것입니다. 객체 지향 애플리케이션은 객체 지향대로 다루고 관계형 데이터베이스는 관계형 데이터베이스대로 설계하고 사용할 수 있도록 중간에서 도와주는 기술일 뿐입니다. 그리고 ORM의 태생 자체가 관계형 데이터베이스의 중요성을 인식하고 나온 기술입니다.



fender 님의 댓글

ORM은 외국에서도 꾸준히 논란이되는 주제이긴 합니다. ORM이 대세인가 아닌가 하는 문제는 다소 애매한 구석이 있는 데, 우선 자바에 국한해서 이야기를 해보자면, ORM은 엔터프라이즈 자바의 초창기부터 지금까지 꾸준히 관심을 받는 개념이었고 지금은 JPA로 인해 확고한 표준의 위치를 유지하고 있다고 할 수 있습니다.

탑링크(TopLink) 같은 ORM 제품은 2000년도 이전부터 엔터프라이즈 자바의 역사와 함께 했고, ORM 기술은 EJB 1.0 시절부터 CMP라는 형태로 표준화되기 시작했으며, 초기 CMP의 단점을 개선하기 위해 출발한 하이버네이트는 벌써 2000년 중후반부터 사실상의 표준으로 널리 쓰이고 있었습니다.

국내 SI 프로젝트에서 ‘하이버네이트’나 ‘JPA’라는 이름이 간간히 들리기 시작한 것이 얼마되지 않았다고 해서 해당 기술이 외국에서도 널리 쓰이지 않는 실험적 기술이라고 착각해선 안될 것입니다.

그리고, 원문에서 인용한 ORM의 비판 중, ‘ORM과 같은 기술은 변하지만 RDBMS는 그렇지 않기 때문에 데이터베이스가 몸통이다’와 같은 내용이 있는데, 이는 어떤 의미에선 엔터프라이즈 자바의 발전 방향과 정면으로 배치되는 이야기라고 봅니다.

애초에 왜 ‘웹 응용프로그램 서버(WAS)’라는 개념이 등장했고, 그런 제품군을 왜 ‘미들’웨어 라고 부르는지 생각해보면 이러한 흐름을 조금 더 정확히 이해할 수 있을 지 모르겠습니다.

미들웨어의 시대 이전 비즈니스 로직은 대체로 ‘클라이언트-서버(CS)’의 형태로 클라이언트에 하드코드 되거나 아니면 프로시저와 트리거 등을 통해 데이터베이스 자체에서 관리되고 있었습니다.

그러던 중 비즈니스 로직을 클라이언트로 배포하거나, 프로시저는 자바와 같은 객체지향 언어 처럼 충분한 추상화/모듈화 기능을 제공할 수 없는 단점이 부각되고 아키텍트 들은 기업의 가장 중요한 비즈니스 로직은 클라이언트와 데이터베이스라는 양 극단이 아닌 ‘중간’ 지점에서 관리되어야 한다는 결론에 도달하고, 그것이 지난 세대 동안 엔터프라이즈 자바와 미들웨어 제품군이 각광받게된 주요 원인이 되었습니다.

그리고 비즈니스로직 구현이 SQL 대신 객체지향 언어의 역할로 넘어온 이상, 중요한 것은 RDBMS의 스키마가 아닌 도메인 클래스의 계층구조가 되는 것은 당연한 수순이었고, 그런 흐름에서 ORM 기술의 대두는 당연하게 이해할 수 있는 현상입니다.

따라서 RDBMS와 자바 계층 중 어느 쪽이 ‘꼬리’고 ‘몸통’인지를 묻는다면 원문의 인용글과는 달리, 최소한 엔터프라이즈 자바의 대세는 “데이터베이스가 꼬리다”라는 답을 내는 방향으로 발전해왔다는 것은 분명합니다.

하지만 현실적으로 자바 계층에 맞춰서 데이터베이스 스키마를 설계할 수 없는 프로젝트가 상당히 많은 건 사실이고, 이런 경우 ORM을 염두에 두지 않고 설계된 리거시 스키마를 그대로 두고 바틈업(bottom-up) 방식으로 구현하는 접근을 할 수 밖에 없기에 ORM의 장점이 상당히 퇴색되는 것도 사실입니다.

그리고 ORM 기술 자체도 최적화나 복잡도, 혹은 추상화(leaky abstraction) 등의 이유로 꾸준히 비판받아 왔으며, 이로 인해 외국에서도 무시할 수 없는 비중의 ORM에 대한 회의론이 존재합니다.

벌써 2006년에 “ORM은 컴퓨터 사이언스의 ‘베트남 전쟁’이다”라는 글이 상당한 관심과 논쟁을 불러 일으킨 적이 있으며, 자바 이외의 언어로 시각을 넓혀보면, 루비온 레일스의 ActiveRecord와 같이 자바와 같은 방식의 ORM 개념을 받아들인 경우도 있지만, 반면 스칼라와 같이 ORM보다는 SQL 매퍼(Slick)가 확고한 대세로 자리잡은 경우도 확인할 수 있습니다.

종합적으로 보면, 2000년 중반 쯤이라면 엔터프라이즈 개발을 하면서 ORM을 사용하지 않는다면 시대에 뒤떨어졌다거나 리거시 때문에 어쩔 수 없는 선택으로 간주할 수 있었겠지만, 지금 시점에서는 ORM에 대한 회의론도 무시할 수 없는 정도의 목소리를 내고 있고, 또 ORM을 사용하지 않고 영속성 문제를 깔끔하게 처리할 수 있는 대안도 존재하는 상황입니다.

개인적으로는 그럼에도 불구하고 JPA와 같은 순수 ORM의 존재는 의미가 있고, 특히 탑다운 방식의 설계를 채택할 수 있는 경우 장점이 극대화 된다고 생각합니다만, 분명 이전처럼 ORM이 확고한 ‘대세 기술’이라고 하긴 어려운 시점이 된 것 같습니다.

어쩌면 node.js나 스칼라 등의 환경에서 자바의 JPA/하이버네이트의 경우 같이 확고하게 자리 잡은 ORM 기술이 없다는 점도 일정 부분 영향을 주었을 지 모르겠습니다. 그리고 아마도 마이크로 서비스 같은 아키텍쳐가 주류가 된다면 더욱 잘짜여진 도메인 엔티티 같은 개념을 전제로 하는 ORM보단 더 가벼운 접근이 대세가될 가능성도 있습니다.

흥미로우면서도 다소 씁쓸한 점은, 해외에서는 이미 2000년 대에 대세가 되었던 하이버네이트 같은 기술이 이제와서 간간히 국내 SI프로젝트에서 언급되기 시작하고 해외에서도 ‘아직’ 대세가 아닌 신기술로 논쟁이 되고 있다는 것입니다.

어쩌면 추세로 볼 때 해외에서 ORM에 대한 회의론이 승리하고 관련 기술이 완전히 대세에서 벗어 날 때쯤엔 하이버네이트나 JPA가 국내 SI의 확고한 ‘대세 기술’로 등극하게 될지도 모르겠습니다. 스트러츠가 그랬고 스프링이 그랬듯, 일단 해외에서 널리 쓰인 기술은 5-10년의 시차를 두고 국내에서도 대세가 되고 있으니 허황된 예상은 아닐 것 같기도 하네요.

아마도 국내 SI의 경우 미들웨어에 들어가는 비즈니스 로직이 자바 언어의 객체지향적 특성을 살려서 잘 설계되고 지속적으로 리팩터 되는 환경을 찾아 보기 힘들다는 것도 이제까지 ORM이 널리 쓰이지 못한 원인 중 하나가 아니었을까 싶기도 합니다.

국내 SI는 대체로 자바 코드는 데이터베이스와 화면 사이를 이어주는 매개 역할만 담당하는 식으로 개발되는 경우가 많아, 밸류 오브젝트(VO)는 있어도 도메인 엔티티 같은 개념은 존재하지도 않는 설계가 흔하다보니 여전히 데이터베이스 스키마와 프로시저가 시스템의 핵심으로 인식되기 때문에, ORM의 효용성이 발휘되기 힘든 환경이라고 생각합니다.

아마도 시간이 지나면 ORM에 친숙한 개발 인력이 많아지고 시스템도 스키마부터 새로 만드는 경우가 늘다보면 서서히 추세가 바뀌게 되지 않을까 싶습니다. 물론 위에서 언급한 이유로 그 시점에는 오히려 해외에서 ORM은 대세에서 완전히 밀려나 다른 기술로 대체될 가능성도 충분히 존재한다고 봅니다.


zepinos 님의 댓글

저는 다른 시각을 가진 편인데요…일단 전 SQL Mapper 쪽을 선호하는 입장이라는걸 밝혀두고요.

  1. 제가 프로그래밍 할 때 중요시하는 부분 중 하나가 가독성과 인수인계의 난이도입니다. 그래서 Map 보다는 Bean을 쓰는 편이고, Procedure, ORM 보다는 SQL Mapper 을 씁니다. 변수명도 SQL Mapper 을 통해 DB 에서 가져온 것은 DB 에서 많이 쓰는 표기법 그대로 변수명을 사용하고, 프로그램에서 만들어서 떠돌아 다니는 것들은 프로그램에서 많이 쓰는 표기법 그대로 변수명을 사용합니다. 똑같은 사용자 아이디라도 DB 에서 가져온 값이거나 DB 로 그대로 들어갈 값은 user_id, 내부 처리만을 위해서라면 userID, 검색어로 넘어온 것은 searchUser_id…뭐 대충 이런 식이죠. 그럼 최소한 일관성이 있기 때문에 가독성이나 인수인계 시간 등에서 큰 도움이 됩니다. 그런데 ORM 은 매핑하는 걸 봐야 개체와의 연결을 알 수 있다는 문제 때문에 바로 열어서 확인이 가능한 SQL Mapper 보단 확실히 한 단계 이상 확인 시간이 걸릴 때가 많습니다. 그래서 좀 불편해요. (물론 매핑 변수명을 맞추면 동일하다 싶겠지만, ORM 의 목적처럼 DB 스럽지 않게 만드는게 좋을테니…)

  2. ORM 이 쉽고 생산성이 높느냐…란 질문에 전, 그렇지 않다고 대답하고 싶네요. 이건, 1 번과 유사한 내용인데, 나 혼자 할 일이라면 반대의 답이 달리겠지만, 새로운 사람에게 알려주어야 한다면, 그리고 그 사람이 ORM 와 SQL Mapper 는 다뤄보지 못했고, Java 와 Oracle 만 사용해본 사용자다…그렇다면 SQL Mapper 쪽이 훨씬 문제도 덜 생기고 쉽고 생산성도 높다고 생각합니다. 심지어 저 역시도 iBatis 나 MyBatis 는 책도 사본 적도 없고, 남에게 가르쳐줄 때에도 서른장 안팍의 공식 문서 번역해놓은 걸 출력해서 설명해주고 예제 코드 보여주고 끝이었습니다. ORM 들은…좀 더 내용이 심오하죠. 개인적으로 google 노출 빈도로 이야기 하기엔 SQL Mapper 는 훨씬 쉽고 간단합니다.

  3. ORM 은 편리하지만, RDBMS 의 특성을 100% 살리지는 못한다고 생각합니다. 그래서 비교적 간단한 형태의 관계를 가지는 데이터들이라면 ORM 이 어울리지만, 그렇지 않은 경우 참 난해해집니다. Oracle ERP 같은 걸 해보니…ORM 은 엄두가 안나더라구요. 대부분 따로 쿼리를 만들어주시는 분들이 작업을 해주시긴 하셨지만, 그 분들은 ORM 은 모르니…oracle package 로 그냥 만들어주시지만, 좀 간단한 것들은 package 참고해서 SQL Mapper 로 프로그래밍 하는게 훨씬 편하긴 합니다.

  4. ORM  역시 대부분은 일반적인 형태대로 테이블이나 관계 구성을 하면 최적의 환경을 못만들겠더군요. 그래서 ORM 에 맞는 구성을 해둘 경우 더욱 쾌적한 프로그래밍이 가능하다고 느꼈는데, 이것조차 진입장벽이라는게 문제였습니다. 나만 그게 된다면, 이런 일은 다 나에게만 넘어온다는게 너무 실증이 나더군요.

  5. 여담이지만, WAS 쪽에서 연산을 하지 않고 대부분 DB 쪽에서 연산을 하는 이유는…일반적으로 DB 쪽 시스템이 월등히 스펙이 좋은 장비를 쓰기 때문입니다. WAS 쪽에 투자할 돈은 서버 사양보다는 서버 대수를 늘리는 쪽으로 가는게 보통이고, 이것 또한 연산의 분산 때문이 아니라 접속자 수를 늘리기 위한 방편에 가깝다고 보구요. 물론 WAS 쪽에서 연산할 때 더 효과가 좋을 때도 있습니다만, 데이터 조합을 위해 메모리에 혹은 임시 저장소에 데이터를 적재한 뒤 연산하는 과정에서 일부 계산을 추가하는 쪽이 효율이 더 좋습니다. WAS 까지 데이터를 끌고 와서 다시 loop 을 돌면서 한줄씩 처리하는 것보다요.


초보람보님의 댓글

지나가는 행인 수준이지만 뚝 하나 던지고 가 봅니다.
현재 JAVA 생태계에서 JAVA 를 좌지우지하는 꼬리(?)가 몸통(?)을 흔드는 듯한 녀석들이 있습니다.
EJB 를 역사 속으로 사라지게 하는 Spring 이라는 녀석과 JDBC 를 넘어 JPA 라는 표준을 만들게한 Hibernate 라는 녀석이죠.

여기서는 Hibernate  는 이 토론(?)에서 피고에 해당하니 넘어가도록 하고요.
한국 JAVA 개발자들에게 절대적인 존재이자 전세계 JAVA 개발자에게 그 영향력을 행사하는Spring 관점에서 제 의견을 살짝 말씀드리자면 다음과 같습니다.

어차피 JDBC 는 여기 낄 자리가 없어 논외로 한다고 하면 DB 다루는 기술 2개를 Spring 관점에 비교해 보겠습니다.

먼저, SQL Mapper 의 절대자 MyBatis 를 Spring 과 연동해서 사용하기 위한 POM 파일을 한 번 살펴 보죠.

1
2
3
4
5
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis-spring</artifactId>
	<version>1.2.2</version>
</dependency>

이번에는 ORM 을 Spring 과 연동해서 사용하기 위한 POM 파일 보시죠.

1
2
3
4
5
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-orm</artifactId>
	<version>${spring.framework.version}</version>
</dependency>

또는 ORM 의 JAVA 표준인 JPA 를 아주 아주 편안하게 사용하기 위해 아래와 같이 하실 수도 있습니다.

1
2
3
4
5
<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-jpa</artifactId>
	<version>${spring.framework.version}</version>
</dependency>

MyBatis 를 사용하기 위해서는 org.mybatis 에서 제공하는 jar 를 사용합니다.

ORM/JPA 를 사용하기 위해서는 org.springframework 에서 제공하는 jar 를 사용합니다.

향후 변화가 있을 수도 있겠지만 Spring 팀에서는 더 이상 공식적으로 SQL Mapper 를지 원하지 않는다는 것을 단적으로 보여줍니다.

MyBatis 가 iBatis 이던 시절 DAO 에 import 되는 내용은 import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport; 였습니다. 그런데 MyBatis 로 옮겨지면서 DAO 에는 import org.mybatis.spring.SqlSessionTemplate; 입니다.


Spring 팀은 전세계 개발자들로부터 의견을 수렴하고 또 어마 무시한 고민 끝에 ORM 을선택했을 겁니다. 이러한 Spring 팀의 결정은 시사하는 바가 크다고 봅니다.

그리고 제가 경험한 것을 기초로 하자면 SQL Mapper 를 사용하는 경우 DBA 와 개발자의 경계는 무척이나 선명한 편입니다.
ORM 을 사용하게 되면 이 경계가 살짝(?) 모호해 지죠. 
DBA 의 많은 역할이 개발자에게 오는 느낌입니다.
그래서 제가 보고 있으면 ORM 을 도입하고자 할 때 양대 세력의 반발을 경험하게 됩니다.

ORM 을 위해서 DBA 는 O 를 알아야 하고 개발자는 R 을 알아야 하고 두 보직 모두는 M 을 알아야 하는데 국내 환경에서 O 를 아는 DBA, R 을 아는 개발자가 많치 않기에 또는 이를 학습하거나 적용할 시간이 되는 DBA, 개발자가 많치 않기에 ORM 도입이 더딘 것이 아닌가 생각해 봅니다.


그리고 Spring 을 학습하면서 DI, AOP, PSA, 설계 정보를 학습하라고 하지만 100명의 개발자가 투입되는 현장에서 99명은 @Controller, @Service, @Repository,@Resource/@Autowirted,@RequestMapping 정도만 쓰고, 결국 단 한명의 개발자만 @Configulation, @Bean, @ComponetScan,AOP, PSA 를 아주 유연하게 사용하면 되더군요.

ORM 도 이런 길을 걷지 않을까라는 생각을 하게 됩니다. DBA 나 수석(?) 개발자가 @Entity, @Id,@Column, @OneToMany 등등을 적용한 Java Class 들을 나머지 개발자들을 위해 제공하면 되지 않을까 싶습니다.

과거에 웹 분야에는 디자이너와 개발자만 있다가 언제 부터인가 퍼블리셔라는 직군이 생겨났듯 향후에는 JAVA 개발자와 DBA 사이에 ORMer 가 생길지도 모른다는 상상을 해 보게 되네요.

IT 환경의 내일을 예측하는 것은 주식 시장을 예측하는 것과 같다고 하더군요.
저는 글을 작성하신 김영한님의 JPA 서적을 보면 다가오는 내일을 준비해 보려합니다.

끝으로.

양 극단은 항상 틀리다는 말이 생각나네요. 

그리고 빨간색과 보라색은 무지개의 양 끝단에 있지만 결국 같은 무지개 위에 있다는 말도 스치는 밤입니다.


urbug2 님의 댓글

ORM 에 대해서 좀 많이 회의적인 입장을 가진 사람입니다.

orm 을 통해서 얻을 수 있는 장점은 좀 더 객체지향적인 기분을 내면서 코딩을 할 수 있다는 점인데.. 그렇기 때문에 회의적입니다.

첫째로, SI에서 비지니스를 풀면서, 객체지향적인 코딩이 필요한 순간이 얼마나있겠냐는 점입니다.
업무단을 다루면서는 거의 없을 것 같습니다
적어도 application architecture 에서 이슈를 풀어 갈 때, 객체지향이 힘을 발휘하는데. 이 쯤 되면 ORM이 직접생성한 VO객체를 사용하는 일은 거의 없습니다. 있다 해도 많지도 않습니다.

둘째로, ORM 의 장점을 살리기에는 업무 테이블들이 너무 크고 복잡합니다.

ORM 이 유리할 수 있는 순간은 아주 극히 일부의 경우 밖에 없어 보입니다.

혹시 필자분이 하이버네이트를 써서, 더 유리한 경험이 있었다면 한번 공유해 주셨으면 하네요.
그게 훨씬 설득력 있을 것 같습니다.


fender 님의 댓글

ORM의 효용성을 이해하기 위해서는 시스템을 객체지향적 관점에서 접근한다는 전제 조건이 필요합니다. 사실 데이터베이스 중심적 접근에만 익숙한 개발자라면 경우 JPA라는 용어의 ‘P’가 뜻하는 ‘영속성(Persistence)’라는 개념부터 정확하게 이해하기 힘들 것이라고 생각합니다.

만일 현재 개발중인 시스템에 대해 예컨대 “퇴사 처리는 어떻게 해야하지?”라는 질문을 했을 경우 “이 클래스의 속성을 이렇게 바꾸면 되잖아?”라는 답을 얻을 수 있다면 아마도 해당 도메인 클래스의 인스턴스에 대한 영속성을 확보한다는 측면에서 JPA와 같은 본격적인 ORM 라이브러리 도입이 자연스러운 선택이 될 것입니다.

반면, 같은 질문에 대해 “이 테이블의 이 컬럼값을 바꾸면 되잖아?”라는 답이 먼저 떠오른다면, 이는 해당 프로젝트는 데이터베이스 중심적으로 설계되고 구현되고 있다는 반증이기 쉽습니다. 이 경우 ORM을 도입하면 오히려 하위 계층의 스키마와 쿼리를 감추어 코드만 이해하기 어렵게 만드는 군더더기가 될 공산이 큽니다.

개인적인 의견으로, ORM 도입이 의미가 있기 위해서는 이상적으로는 스키마까지 전체 시스템을 탑-다운(top-down) 방식으로 설계할 수 있거나 아니면 최소한 기존 데이터베이스 스키마 위에 객체지향적으로 잘 설계된 도메인 계층구조가 존재해야 합니다.

도메인/엔티티가 존재하지 않는 상태에서는 영속성을 관리할 대상 자체가 없는 것이니 ORM 개념 자체가 성립하지 않으며, 이를 억지로 적용하기 위해서 데이터베이스의 ‘뷰’와 같은 의미로 테이블 구조와 똑같은 클래스를 만들거나 VO를 엔티티로 대용하는 등의 부자연스런 설계를 하게되어 ORM의 장점을 느낄 수 없는 구현이 되기 쉽습니다.

국내 상당수 (어쩌면 대부분의) SI 프로젝트가 이러한 기준에 미달하고 리거시 데이터베이스 스키마를 중심으로 한 설계를 하고 있다면 그 만큼 보통의 국내 개발자들이 ORM의 효용성을 체감할 기회가 제한적이라는 사실은 익히 짐작할 수 있을 것입니다.

다만 이러한 특수성을 해외의 경우까지 일반화해서 ORM 자체가 현실과 동떨어진 기술이라거나 아직 널리 쓰이지 않는 실험적 성격이라는 착각을 하지 않도록 주의해야 한다고 봅니다.


Quick 님의 댓글

urbug2 님이 말씀하신 부분은 해당 프레임웍 혹은 해당 언어의 철학이나 적절한 이해 없이 잘못 사용하고 있는 것이고, 그건 사실 프레임웍의 문제가 아니라 잘못 사용하고 있는 사람이나 조직의 문제입니다. 그걸로 적합성을 판단하는 것은 무리가 있다고 보구요. 


저 역시 SI에서 제 경력의 대부분을 보냈고 ORM을 사용한 기간보다 SQL Mapper를 사용한 기간이 훨씬 더 오래 되었습니다. 
기존 SI에서 ORM이 녹아들지 못하는 것은 레거시의 설계와 업무의 연속상에서 이미 존재하는 SQL을 분석해야 하고 기 작성된 SQL을 재사용하기 편하기에 꺼려지는 것이 아닐까 싶구요…또 사람이 컨트롤 하기에는 눈으로 보이는 SQL을 가지고 튜닝도 하고 힌트도 때리고 하면서 익숙한 것이기도 할테고요.  실제  SI 판을 제외하고는 ORM이 전반적으로는 널리 쓰여지고 있는 추세라고 봐도 무방할거 같습니다. 

통계등에서 쓰이는 SQL 구문 또한 SQL Mapper로 호출하나 JPQL이든 Query DSL에서 작성해서 호출하던 똑같이 구현하는것은 가능합니다. 다만, 이 경우 복잡한 쿼리를 날리기 위해서 전자는 SQL만 알면 되지만 후자는 해당 구현 기술을 이해하고 있어야 한다는 차이가 있겠죠. 따라서 복잡한 집계성 SQL은 따로 개발을 해야 하는 편이 맞다고 봅니다. 하지만 거의 대부분의 경우 돈계산을 한다던가, sum, count, grouping, having, paging 등이나 몇개 테이블을 조인해서 계산하는 것과 같은 데이터 처리는 충분히 가능합니다. 

보통 DB의 자원은 (트래픽이 지속적으로 늘어난다고 보면) Scale Up을 통해서 성능적인 향상을 꾀해야 하기 때문에 복잡한 로직, 함수, 프로시저등을 통해서 DB자원에 부하를 주는 것보단 비교적 Scale Out이 용이한 아키텍쳐로  구성하는 것이 유리하다고 봅니다. 단순하게 리플리케이션 장비를 늘리거나 디스크를 늘린다고 해서 폭발적으로 늘어나는 데이터를 안정적으로 처리할 순 없으니까요. 

마찬가지로 zepinos 님이 말씀하신 부분은 Learning Curve의 문제이지 생산성의 문제는 아니라고 봅니다. 
SQL Mapper와 ORM의 생산성은 위의 예제처럼 (동일한 수준의 이해가 있다면) CUD를 날리지 않는 것에서 부터 차이가 납니다.
또한, PK 기반으로 단건을 조회하거나, 특정 컬럼의 리스트성 조회 역시 별다른 SQL을 입히지 않아도 자동으로 호출이 됩니다. 

이것은 테이블이 100 단위가 넘어간다면 훨씬 생산성에 효과를 볼수있습니다. 또한 Entity만을 관리하면 되므로 중복 SQL에 대한 것도 거의 대부분 관리될 수 있습니다. 

SQL Mapper 로 이걸 커버하려면 DB 스키마를 읽어와서 컬럼을 기반으로 Generator 를 만들어 주고 Insert, Update, Delete, Select 구문을 파싱하는 라이브러리 정도는 만들어서 적용해줘야 일정 수준정도 (기본기능만) ORM의 생산성을 따라올 수 있을거 같다고 보입니다. 
제 경우에도 몇년전에 XML을 자동으로 생성한다거나 CRUD구문을 SQL없이 실행할 수 있도록 MyBatis를 확장해서 라이브 서비스에 적용해본적이 있고, 현 시점에 ORM을 쓰는 상황에서 그때 만든 라이브러리보단 ORM에서 제공하는 기본 기능들만으로도 생산성 부분은 차이가 난다고 봅니다. 그렇다하더라도 비슷한 쿼리가 호출되는 것 또한 막을수가 없죠. 


마지막으로 SQL을 매핑하는 것과 Relation을 매핑하는 것은 사상이 다른 개념입니다. 즉, MyBatis는 ORM이 아닙니다. SQL을 작성하여 ID를 부여하고, 그걸 호출해서 VO에 컬럼을 매핑하는 Mapper죠.
SQL과 그것을 호출하기 위한 ID, 그 결과물을 저장하기 위한 VO로 이루어진 구조를 가지고 Domain간의 Relation을 판단할수는 없다고 봅니다.
ORM은 Entity 클래스의 구조만으로도 SubType(inheritance)이나  테이블의 결합(연관관계) 를 파악할 수 있습니다.

단편적인 예를 들면, 테이블의 관계를 파악하기 위해 SQL Mapper 는 SQL을 뜯어보거나 ERD같은 문서로 릴레이션을 파악해야 하지만 ORM은 소스 안에서 관계가 설정되어있고 fetch 하는 옵션들도 가지고 있습니다. 

1:N일 때 1을 가져오고 해당하는 N의 관계 테이블을 같이 fetch 하던지, 1 만 가져오고 실제 사용하는 시점에 N의 관계에 있는 테이블을 조회하던지 등등이 entity의 설정으로 녹아 들어있고 relation을 entity만으로도 파악할 수 있죠.
즉, 다른 문서나 SQL같은 것을 보지 않아도 Java 로 작성된 Entity 클래스 하나만 보면 연관된 테이블과 속성값, 컬럼 타입등을 이해할 수 있습니다. (물론 저는 그래도 다른 업무 담당자들과 회의할때를 대비해서 erd는 그려놓습니다)  업무를 분석할때 SQL까지 뜯어보지 않아도 된다는 말이기도 합니다. 

자바 뿐 아니라 다른 언어의 웹 프레임웍들도 요즘은 보통 내부 ORM들을 사용할 수 있도록 내장하고 있는 추세입니다. 
물론 해당 프레임웍들이 널리 (?) 범용적으로 (?) 사용되는 주류인것이냐는 별개의 문제라고 보구요.

어쨋거나 러닝커브와 사상적인 이해가 갑갑한 측면이 존재하긴 하지만 만약 저보고 새 프로젝트에서 써야 할 기술을 선정하라고 하면 저는 아마도 특별한 경우가 아니라면 ORM으로 갈거 같습니다. 
특별한 경우는 기 작성된 SQL들이 많아서 유용할거 같다거나, 구성원들이 ORM을 전혀 모르거나 거부감이 있다거나 하면 SQL Mapper로의 선택도 나쁘지 않은 선택지 라고 보입니다. 물론 이게 정답인거다 라고 주장하는것은 아니구요. 그렇다고 SQL Mapper가 후지다고도 생각하지 않아요. CRUD만 제너레이터 적용해서 좀만 확장하면 전 아직도 MyBatis가 더 익숙하긴 합니다.. 

Tags:

Updated:

Leave a comment