꿈소년의 개발 이야기

[스프링 부트 개발자 온보딩 가이드 스터디] 복잡한 실제 비즈니스 요구사항과 JPA 코드 구조 잡기 본문

Do it 스터디!/스프링 부트 개발자 온보딩 가이드 스터디!

[스프링 부트 개발자 온보딩 가이드 스터디] 복잡한 실제 비즈니스 요구사항과 JPA 코드 구조 잡기

fogthegreat 2026. 4. 3. 20:24
반응형

DAY 6

🔖 오늘 읽은 범위 :
🌱공부 내용: Chapter 05 복잡한 실제 비즈니스 요구사항에 대해 JPA 코드 구조를 어떻게 잡아야 하나?
👢쪽수: p.217-p.218


Q. 실제 비즈니스 요구사항이 복잡해질 때 JPA 코드 구조를 어떻게 잡아야 하나요?

책임 분리(Separation of Concerns)

  • JPA 를 이용한 백엔드 개발에서 가장 중요한 설계 원칙 중 하나 ⇒ ‘책임의 분리’
  • 각 계층(엔티티, 리포지토리, 서비스, 컨트롤러, DTO, 매퍼 등)이 맡아야 할 역할을 명확히 나누면 코드가 복잡해져도 수정 위치와 문제 원인 파악이 쉬워진다.
  • 변화에 강하고 유지보수가 쉬우며, 실무에서 여러 개발자가 동시에 협업할 때도 혼란을 줄여준다.

1. 비즈니스 로직은 서비스 레이어에 집중하세요.

가장 좋은 방법은 복잡한 비즈니스 로직을 ‘서비스 레이어’에 집중하는 것이다.

엔티티는 데이터 구조와 관계만 담당한다.

리포지토리는 데이터 저장/조회와 같은 데이터 접근 책임만 진다.

서비스 레이어는 여러 엔티티를 조합하거나, 특정 업무 규칙을 적용하거나, 트랜잭션 처리가 필요한 복잡한 상황을 담당한다.

책임을 나누면 영향을 받지 않고 코드가 훨씬 깔끔해진다.

2. DTO와 매퍼로 입출력을 명확히 분리하세요.

엔티티 객체를 그대로 API 의 입력값이나 응답값으로 사용하는 경우는 거의 없다.

외부와 통신하는 API 입출력은 DTO로 분리하는 것이 좋다.

DTO 는 실제 API 요구사항에 맞춰 설계한다.

엔티티와 DTO 사이의 데이터 변환은 매퍼(MapStruct, ModelMapper 또는 직접 작성한 매퍼 변환 매서드 등)를 통해서 관리한다.

API 스펙이 변경되어도 엔티티는 보호된다.

엔티티가 변경되어도 API 스펙에는 영향이 없다.

변환 로직이 하나로 모여 있으면 유지보수도 쉬워진다.

3. 리포지토리는 쿼리만 담당하고, 복잡한 조회는 별도로 관리하세요.

리포지토리의 역할

  • 데이터베이스에 쿼리를 실행해 데이터를 가져오거나 저장하는 것.
  • 간단한 CRUD 기능이나 단순 조회는 리포지토리에서 직접 처리한다.

커스텀 리포지토리 구현체 또는 MyBatis, QueryDSL, Native Query 등 다양한 쿼리 프레임워크:

  • 매우 복잡한 통계, 동적 조검 검색, 여러 테이블 조인이 필요한 상황 등등 복잡한 쿼리가 필요한 경우에 활용한다.

특정 비즈니스 요구에 맞는 복잡한 쿼리만 따로 구현하고 테스트 할 수 있다.

4. 엔티티는 최대한 ‘순수’하게 유지하세요.

엔티티: 데이터베이스 테이블 구조와 1:1 로 매핑되는 객체.

엔티티는 데이터 자체와 그 관계만을 표현하는 데 집중하는 것이 좋다.

엔티티 간 연관 관계도 단방향 위주로 한다.

지연 로딩(FetchType.LAZY)을 적극적으로 사용해 불필요한 데이터 로딩을 막는 것이 좋다.

엔티티는 최대한 순수하게, 데이터를 담는 역할에만 충실하도록 설계한다.

5. 엔티티 설계와 API 설계를 분리해서 생각하세요.

가장 많이 하는 실수

  1. 엔티티 구조에 맞춰 API 를 만드는 것.
  2. API 요구사항에 맞추려고 엔티티를 자주 변경하는 것.

API 입출력 구조는 DTO에서 정의하고, 엔티티와 별도로 설계해야 한다.

API 요구 사항이 자주 변한다면, 이런 분리가 안정성을 크게 높여준다.

반응형