DataSource → SqlSessionFactory → Mapper Scan
MyBatis를 “코드 사용” 관점에서 보면 Mapper 인터페이스만 만들면 되는 것처럼 보인다.
하지만 그게 동작하려면 컨테이너(스프링) 쪽에서 연결을 해줘야 한다.
핵심 연결은 딱 3단계이다.
- DataSource 준비 (HikariCP)
- SqlSessionFactory 준비
- Mapper Scan 등록
// ================================
// [JDBC DAO에서 반복되는 코드] 자원 얻기/닫기 + ResultSet 매핑
// - MyBatis가 주로 줄여주는 부분이 여기다
// ================================
public class TodoJdbcDao {
private final DataSource ds;
public TodoJdbcDao(DataSource ds) {
this.ds = ds;
}
public List<TodoVO> findAll() throws SQLException {
String sql = "select tno, title, finished from tbl_todo order by tno desc";
try (Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
List<TodoVO> list = new ArrayList<>();
while (rs.next()) {
TodoVO vo = new TodoVO(
rs.getLong("tno"),
rs.getString("title"),
rs.getBoolean("finished")
);
list.add(vo);
}
return list;
}
}
}
1) DataSource: DB 연결을 제공하는 창구
MyBatis도 결국 DB와 연결해야 SQL을 실행한다.
그래서 MyBatis는 DataSource를 필요로 한다.
여기서는 이미 앞에서 만든 HikariCP(DataSource)를 그대로 쓴다고 보면 된다.
즉 “풀에서 Connection을 빌려오는 창구”가 DataSource이고,
MyBatis는 그 창구를 통해 Connection을 얻는다.
2) SqlSessionFactory: MyBatis 실행의 핵심 공장
MyBatis에서 실제 SQL 실행 단위는 SqlSession이다.
그리고 그 SqlSession을 만들어내는 공장이 SqlSessionFactory이다.
즉 구조는 이렇게 이해하면 된다.
- SqlSessionFactory → SqlSession 생성
- SqlSession → SQL 실행, 트랜잭션, 매핑 수행
실무에서 개발자가 SqlSession을 직접 다루기보다는
스프링 연동을 통해 Mapper를 주입받아 쓰는 경우가 많지만,
내부적으로는 SqlSession이 움직인다고 보면 된다.
3) Mapper Scan: 인터페이스를 찾아 “프록시 구현체”를 만든다
MyBatis의 가장 큰 특징 중 하나가 이거다.
- Mapper 인터페이스만 만들고
- 구현 클래스는 만들지 않는다
대신 MyBatis가 프록시 구현체를 만들어서 스프링 빈으로 등록한다.
이걸 가능하게 하는 게 Mapper Scan이다.
즉 scan의 의미는 이런 것이다.
지정한 패키지를 훑어서 Mapper 인터페이스를 찾고,
그 인터페이스의 구현체(프록시)를 만들어 빈으로 등록한다
그래서 TodoMapper 같은 인터페이스를 서비스에서 바로 주입받아 쓸 수 있다.
// ================================
// [MyBatis Mapper 인터페이스 예시] (어노테이션 기반)
// - 구현 클래스를 내가 만들지 않는다
// - MyBatis가 프록시 구현체를 만들어준다
// ================================
@Mapper
public interface TodoMapper {
@Select("select tno, title, finished from tbl_todo order by tno desc")
List<TodoVO> findAll();
@Insert("insert into tbl_todo(title, finished) values(#{title}, #{finished})")
int insert(TodoVO vo);
}
XML 매퍼 파일을 쓰면 mapperLocations가 추가된다
MyBatis에서 SQL을 XML로 분리해서 관리한다면
SqlSessionFactory에 매퍼 파일 위치를 알려줘야 한다.
보통 이런 형태로 등록한다.
- classpath*:mappers/**/*.xml
이 설정이 있으면 resources 아래의 mappers 폴더 하위 XML 파일들을 찾아서 읽는다.
전체 흐름
- HikariCP(DataSource)가 Connection을 제공한다
- SqlSessionFactory가 SqlSession을 만든다
- SqlSession이 SQL 실행과 매핑을 수행한다
- Mapper Scan이 Mapper 인터페이스를 찾아 프록시 빈을 만든다
- 서비스는 DAO 대신 Mapper를 주입받아 사용한다
정리
- MyBatis 설정은 DataSource → SqlSessionFactory → Mapper Scan 순서로 연결된다
- SqlSessionFactory는 SqlSession을 만드는 공장이다
- Mapper Scan이 Mapper 인터페이스 구현체(프록시)를 자동으로 만든다
- XML 매퍼를 쓰면 mapperLocations 설정이 필요하다
'Web > Web Basics' 카테고리의 다른 글
| [스프링과 스프링 MVC] 2. 스프링 MVC는 “프론트 컨트롤러”로 움직인다 (0) | 2026.03.30 |
|---|---|
| [스프링과 스프링 MVC] 1. DI와 빈(Bean) (0) | 2026.03.30 |
| [상태 유지와 공통 처리] 4. MyBatis는 무엇을 해결하는가 (0) | 2026.03.30 |
| [상태 유지와 공통 처리] 3. Connection Pool / DataSource / HikariCP (0) | 2026.03.30 |
| [상태 유지와 공통 처리] 2. JDBC란? (0) | 2026.03.30 |