Java

[Java] ORM의 탄생, SQL 중심적인 개발의 문제점

뚜코맨 2024. 2. 6. 00:41

패러다임의 불일치

우리가 가장 많이 사용하는 프로그래밍 패러다임은 단연 객체지향이다. 내가 공부하고 있는 언어인 자바도 객체지향 언어이다. 그리고 우리가 가장 많이 사용하는 데이터베이스는 관계형 데이터베이스이다. MySQL, MariaDB, Oracle 등 모두 다 관계형 데이터 베이스이다. 우리는 지금 객체를 관계형 데이터베이스에 저장하고 관리하는 시대이다. 

 

이런 패더라임의 불일치로 인한 SQL 중심적인 개발은 많은 문제점이 있다.

 

SQL 중심적인 개발의 문제점

1. 반복적인 객체-테이블 매핑과 CRUD

객체지향, 관계형 데이터베이스는 패러다임의 불일치로 우리는 추가적인 작업을 해야한다. 객체를 관계형 데이터베이스에 저장하고 꺼내오기 위해서는 객체를 테이블로, 테이블은 객체로 매핑하는 작업을 우리 개발자가 하고 있다. 이런 매핑 작업은 테이블의 구조가 변경되면, 코드 모든 SQL문을 변경된 테이블의 구조에 맞게 수정해야한다.

 

그리고 흔히 CRUD라고 말하는 기능은 일반적으로 거의 모든 테이블에서 필요하다. 100개의 테이블이 존재한다면 100개의 CRUD 코드는 필요할 것 이다. 이런 시대에서 우리 개발자들은 사실 비즈니스 로직보다 SQL 매핑 작업에 더 많은 시간을 할애해야할 수도 있다.

 

2. 객체 그래프 탐색의 어려움

객체지향에서 객체간의 연관관계는 참조를 통해 맺어지고, 관계형 데이터베이스에서 테이블 간의 연관관계는 외래키(FK)로 이루어진다. SQL 중심적으로 코드를 작성하면 객체의 구조는 테이블에 맞춰야한다.

 

3. 진정한 계층 분할이 어렵다.

실제 객체간의 연관관계와 상관없이, 쿼리문에 따라 객체 그래프의 탐색 범위가 제한된다. 실제 객체 그래프와 관련없이, 실제 쿼리문이 어떤 테이블을 가져오느냐에 따라 탐색할 수 있는 범위는 제한된다. 이런 문제는 아래와 같은 문제를 낳는다. 코드로 살펴보자.

User user = userDAO.find(userId);
user.getOrder(); // 어떤 값인지?
user.getAddress().getZipCode(); //NPE가 발생하는지?

 

위의 코드를 안전하게 사용하려면, getAddress를 호출하는 개발자가 userDAO.find() 내부적으로 Address 테이블과 Join하는지를 확인해야한다. Address 테이블과 Join 하지않는다면 user.getAddress()는 null일것이다. 즉, 엔티티를 신뢰할 수 없는 문제가 발생한다.

 

ORM의 등장

객체를 데이터베이스에 저장하고 관리하는 것이 컬렉션처럼 간단하면 얼마나 좋을까? DB작업을 객체를 컬렉션에 저장하는 것 처럼 추상화 하기 위해, 객체지향과 관계형 데이터베이스간의 패러다임 불일치를 해결하고 SQL 중심적인 개발에서 벗어나 객체 중심으로 개발하기 위해 ORM(Object-Relational-Mapping) 이라는 말 그대로 객체-관계형 데이터베이스를 매핑해주는 기술이 등장했다. 그리고 자바 진영에서는 JPA 라는 ORM 기술 표준이 존재한다.

 

ORM, JPA에 대해서 나중에 중점적으로 다뤄볼 예정이다.