15-M2. Mapper → DB: SQL 실행
MyBatis는 Mapper 메서드 호출을 SqlSession으로 넘기고, 다시 Executor, StatementHandler, PreparedStatement 계층을 통해 실제 SQL을 실행합니다.
이 단계는 MyBatis가 DB에 닿는 실제 호출 체인을 보여줍니다.
이번 단계의 역할
Mapper 호출을 JDBC 실행까지 연결하는 구간입니다. 즉 인터페이스 메서드가 실제 SQL 실행으로 바뀌는 단계입니다.
호출 흐름 요약
MapperMethod.execute(...)가sqlSession.selectOne(...)을 호출합니다.DefaultSqlSession.selectOne(...)은 내부적으로selectList(...)를 사용합니다.SimpleExecutor.doQuery(...)가StatementHandler를 준비합니다.PreparedStatementHandler.query(...)가ps.execute()를 호출합니다.
호출 흐름 다이어그램
sequenceDiagram
participant Method as MapperMethod
participant Session as DefaultSqlSession
participant Exec as SimpleExecutor
participant PS as PreparedStatementHandler
participant DB
Method->>Session: selectOne(statement, param)
Session->>Exec: executor.query(...)
Exec->>PS: handler.query(stmt, resultHandler)
PS->>DB: ps.execute()
핵심 코드
// MapperMethod.java
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param);
// DefaultSqlSession.java
public <T> T selectOne(String statement, Object parameter) {
List<T> list = this.selectList(statement, parameter);
if (list.size() == 1) {
return list.get(0);
}
return null;
}
// SimpleExecutor.java
Statement stmt = prepareStatement(handler, ms.getStatementLog());
return handler.query(stmt, resultHandler);
// PreparedStatementHandler.java
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
return resultSetHandler.handleResultSets(ps);
코드 해설
MyBatis는 selectOne()이라고 부르지만, 내부적으로는 먼저 리스트 조회를 수행하고 결과 개수를 검사합니다.
그리고 실제 JDBC 실행은 PreparedStatementHandler.query()의 ps.execute()에서 일어납니다.
설계 의도
Mapper, 세션, 실행기, StatementHandler를 분리해 SQL 실행 파이프라인을 확장 가능하게 만들기 위한 구조입니다. 덕분에 캐시, 플러그인, 로깅, 결과 처리 전략을 중간에 쉽게 끼워 넣을 수 있습니다.
다음 단계 연결
다음 문서 15-M3에서는 DB가 돌려준 결과를 MyBatis가 어떻게 ResultSetHandler로 처리하는지 봅니다.