Mapper vs Repository: 데이터 엑세스 계층 비교

허진혁·2023년 9월 12일
1

givemeticon 프로젝트

목록 보기
2/10

🤔 고민사항

새로운 프로젝트에 들어가서 Mybatis를 사용하려고 하는데, 아키텍처 상 mapper와 repository가 비슷한 역할을 한다는 느낌을 받았습니다. 하지만 분명히 두 개념을 달랐기에 비교하고 언제 어떤 것을 사용해야할지 살피는 것이 이 글의 목적이에요.

(자료를 탐색하기 전 떠올렸던 방식은 아래의 두 가지 흐름)

Controller - Service - Mapper(Interface) → mapper.xml → DB

Controller - Service - Repository → Mapper(Interface) → mapper.xml → DB

🚌 데이터 엑세스 계층

두 개념이 비슷하다는 생각을 했던 이유는 바로 DB에 접근하는 계층이었기 때문이에요.

데이터 엑세스 계층은 모든 애플리케이션에서 필수적인 부분 중 하나에요. 데이터베이스와의 상호작용, 데이터 검색 및 조작 등과 관련된 중요한 역할을 갖고 있어요. 이 데이터 엑세스 계층을 구성하는 데 있어 Mapper와 Repository는 두 가지 주요 접근 방식이에요.

또한, Repository와 Mapper는 ORM에서 개념적으로 사용되는 두 가지 주요 패턴이며, 이들의 차이점은 주로 ORM 라이브러리나 프레임워크마다 약간 다를 수 있어요.

Ⓜ️ Mapper

Mapper는 데이터베이스와 애플리케이션 간의 상호작용을 처리하는 객체에요. 주로 SQL 쿼리를 사용하여 데이터베이스에서 데이터를 가져오거나 데이터를 데이터베이스에 저장하는 데 사용하죠.

DataMapper 는 "객체와 데이터베이스 간에 데이터를 이동하면서 서로 독립적으로 유지하고 매퍼 자체를 유지합니다"(Fowler, PoEAA)

마틴파울러가 정의한 것을 기반으로 문구를 해석해보면,

  • "객체와 데이터베이스 간에 데이터를 이동하면서": DataMapper 패턴이 데이터베이스로부터 데이터를 읽어와 객체로 매핑하거나, 객체의 데이터를 데이터베이스에 저장할 때 사용되는 패턴임을 나타내요. 즉, 데이터의 이동과 변환 작업을 수행하는 역할임을 알 수 있어요.
  • "서로 독립적으로 유지하고": 객체와 데이터베이스 간에 서로 독립적으로 변화할 수 있음을 의미해요. 즉, 데이터베이스 스키마의 변경이나 객체 모델의 변경이 서로에게 영향을 미치지 않도록 하는 것이에요. 이것은 유지보수성을 향상시키고 시스템의 유연성을 높이는 데 중요한 부분이에요.
  • "매퍼 자체를 유지합니다": DataMapper 패턴이 객체와 데이터베이스 간의 매핑 로직을 유지하고, 이를 분리된 매퍼 클래스에 보관하는 것을 의미해요. 이로써 매퍼 클래스는 재사용 가능하고 관리가 쉬워져요.

정리해보면, Mapper는 객체와 데이터베이스 간의 매핑을 처리하는 역할로써 객체와 데이터베이스 테이블 사이의 변환을 담당하여 객체와 테이블 간의 속성 매핑을 수행하는 것이에요.

Ⓡ Repository

Repository는 데이터 엑세스 계층에서 데이터를 관리하고 엔티티(데이터베이스 레코드)에 접근하는 인터페이스를 정의하는 패턴이에요. Repository 인터페이스를 통해 데이터베이스와 상호작용할 수 있으며 구현체는 백그라운드에서 실제 데이터베이스 엑세스를 처리해요.

Repository 는 일반적인 개념이며 반드시 데이터베이스에 아무것도 저장할 필요가 없습니다. 주요 기능은 도메인 개체에 대한 (쿼리 지원) 액세스와 같은 컬렉션을 제공하는 것입니다(데이터베이스에서 가져오는지 여부는 중요하지 않습니다). 저장소에는 DataMappers 자체가 포함될 수 있으며 종종 포함될 것입니다.

레포지토리는 강력한 쿼리 기능을 갖춘 도메인 개체 모음처럼 작동합니다(Evans, DDD)

에릭 에반스가 정의한 것을 기반으로 문구를 해석해보면,

  • "레포지토리는": 데이터베이스와 상호작용하는 객체이며,
  • "강력한 쿼리 기능을 갖춘": 레포지토리가 데이터베이스로부터 데이터를 검색하거나 조작할 때, 다양한 검색 및 조작 기능을 갖추고 있고,
  • "도메인 개체 모음": 도메인 모델에 속하는 여러 도메인 개체(객체)를 모아놓은 컬렉션이에요.

정리해보면, Repository는 데이터베이스와 직접 상호작용을 담당하는 역할을 해요. 객체 지향적인 인터페이스를 제공하여 개발자가 데이터베이스 연산(CRUD)을 더 쉽게 수행할 수 있도록 도와줘요. Repository 패턴을 사용하면 SQL 쿼리를 직접 작성하지 않아도 되며, 복잡한 데이터 조작 로직을 캡슐화하여 관리할 수도 있어요.

차이점

두 개념의 역할을 기준으로 차이점을 정리해 보았어요.

Mapper의 주요 역할과 특징은 다음과 같아요.

  • 데이터 매핑: Mapper는 데이터베이스로부터 읽어온 데이터를 객체로 매핑하거나, 객체의 데이터를 데이터베이스에 저장할 때 사용됩니다. 이것은 데이터베이스 레코드와 애플리케이션 내의 객체 간의 매핑을 담당합니다.
  • SQL 쿼리 작성: Mapper는 SQL 쿼리를 작성하고 실행하여 데이터베이스에서 데이터를 검색하거나 조작합니다. 이는 데이터베이스와 직접적인 상호작용을 가능하게 합니다.
  • 매핑 로직 관리: Mapper는 데이터베이스 스키마와 객체 모델 간의 매핑 로직을 관리하고 유지합니다. 이로써 데이터베이스 스키마 또는 객체 모델의 변경이 서로에게 영향을 미치지 않도록 합니다.

Repository의 주요 역할과 특징은 다음과 같아요.

  • 데이터 관리: Repository는 데이터베이스에서 데이터를 읽고 쓰는 등의 데이터 관리 작업을 수행합니다. 엔티티(도메인 객체)의 데이터를 데이터베이스로부터 가져오거나 데이터베이스에 저장합니다.
  • 쿼리 추상화: Repository는 데이터베이스 연산(CRUD - 생성, 읽기, 갱신, 삭제)을 추상화하여 개발자가 SQL 쿼리를 직접 작성하지 않고도 데이터를 검색하거나 조작할 수 있도록 도와줍니다.
  • 도메인 로직 캡슐화: Repository는 도메인 개체에 대한 액세스를 제공하면서 도메인 로직과 데이터 액세스를 분리합니다. 이로써 도메인 로직을 개발하기 더 쉽게 만들어줍니다.

정리

Repository는 Mapper의 상위 개념으로 본다면 이해하기 편한 것 같아요.
이 지식을 바탕으로 정리하면,
Mapper는 데이터베이스와 애플리케이션 간의 데이터 매핑과 SQL 쿼리 작성에 중점을 두며, Repository는 데이터 액세스 계층에서 데이터 관리와 쿼리 추상화를 중점을 두었어요.

선택

저는 Controller - Service - Mapper(I) → mapper.xml → DB 방식을 선택하기로 했어요. 이유는 다음과 같아요.

  1. 직접적인 데이터 액세스 제어: Mapper를 직접 사용하여 데이터베이스와 상호작용합니다. 이는 데이터 액세스 레이어를 더 직접적으로 제어할 수 있습니다.

  2. SQL 쿼리의 직접적인 관리: SQL 쿼리가 직접적으로 mapper.xml 파일에 정의됩니다. 이로써 SQL 쿼리의 버전 관리 및 유지보수가 더 효율적으로 이루어질 수 있습니다.

하지만 위의 방식을 선택하여 다음과 같은 사항을 고려해야 해요.

  1. 보안: 직접적인 SQL 쿼리 작성 시 SQL 인젝션 등의 보안 문제를 고민해야 합니다.

  2. 유지보수: SQL 쿼리의 유지보수 및 버전 관리를 직접 해야 하므로 주의가 필요합니다.

참고자료

What exactly is the difference between a data mapper and a repository?

profile
Don't ever say it's over if I'm breathing

0개의 댓글