15-M4. Mapper → Service: DTO / VO 반환
MyBatis는 ResultSetHandler가 만든 결과 객체를 다시 MapperMethod.execute(...) 반환값으로 내보내고, 최종적으로 서비스 계층이 이를 받습니다.
즉 SQL 결과가 다시 애플리케이션 코드에서 사용할 수 있는 DTO/VO로 돌아오는 단계입니다.
이번 단계의 역할
MyBatis 내부 결과 처리 결과를 서비스가 사용할 수 있는 반환 객체로 마무리하는 단계입니다.
이 구간이 끝나면 서비스는 JDBC나 ResultSet을 전혀 보지 않고 DTO/VO만 받게 됩니다.
호출 흐름 요약
DefaultResultSetHandler.handleResultSets(...)가 결과 목록을 반환합니다.DefaultSqlSession.selectOne(...)이 단건 결과를 꺼냅니다.MapperMethod.execute(...)가 그 결과를 그대로 반환합니다.- 서비스가 최종 DTO/VO를 받습니다.
호출 흐름 다이어그램
sequenceDiagram
participant RSH as DefaultResultSetHandler
participant Session as DefaultSqlSession
participant Method as MapperMethod
participant Service
RSH-->>Session: List
Session-->>Method: T
Method-->>Service: DTO / VO
</div>
---
## 핵심 코드
```java
// DefaultResultSetHandler.java
return collapseSingleResultList(multipleResults);
```
```java
// DefaultSqlSession.java
if (list.size() == 1) {
return list.get(0);
}
```
```java
// MapperMethod.java
return result;
```
---
## 코드 해설
MyBatis는 SQL 결과를 `List`로 모은 뒤, `selectOne()`이라면 단일 객체로 꺼내 반환합니다.
그래서 서비스는 일반 메서드 반환값처럼 DTO/VO를 받게 됩니다.
---
## 설계 의도
SQL 실행 결과를 JDBC 자료구조가 아니라 애플리케이션 친화적인 객체로 마무리하기 위한 단계입니다.
이 덕분에 서비스는 데이터 접근 구현 세부를 몰라도 됩니다.
---
## 다음 단계 연결
다음 문서 [16번](/deep-dive/java-web/16/)에서는 JPA/MyBatis 어느 경로를 탔든, 서비스 결과가 다시 컨트롤러로 돌아오는 공통 흐름을 봅니다.