MyBatis

Configuration boundary

XML bean 등록과 mapper scanner 설정 예시는 source의 Spring configuration 관례를 보존한 것이다. 핵심은 mapper boundary, parameter binding, dynamic SQL이며, 현재 application의 configuration recipe를 그대로 지시하지 않는다.

MyBatis는 Java Object와 SQL 문 사이의 자동 매핑을 지원하는 Persistence Framework다. 핵심은 SQL을 Java 코드 밖의 별도 파일(Mapper XML)로 분리하고, Java 객체와 SQL 파라미터/결과 사이의 매핑 작업을 대신 처리하는 것이다.[1] Spring과 함께 쓸 때는 MyBatis 관련 Bean을 Spring Container에 등록하고, Spring의 트랜잭션 기능을 함께 쓰면 Spring Transaction의 @Transactional 기반으로 트랜잭션을 처리할 수 있다.[1:1] 이를 Spring Framework Core의 PSA/DI 사례로 보고 JPA·MyBatis 어느 쪽을 쓰든 @Transactional이 동일하게 트랜잭션을 관리한다고 연결하는 것은 이 page의 해석이다.

MyBatis vs JPA/Hibernate

구분 MyBatis JPA/Hibernate
패러다임 SQL Mapper — SQL을 직접 작성 ORM — SQL을 자동 생성
SQL 제어 개발자가 완전 제어 Framework가 생성
학습 곡선 낮음(익숙한 SQL 그대로) 높음(새 패러다임)
쿼리 튜닝 직접 SQL 작성이라 쉬움 JPQL/Criteria 작성, 생성 SQL 이해 필요
국내 점유율 매우 높음(SpringBoot + MyBatis 조합) 상대적으로 낮음

MyBatis 3 주요 컴포넌트

flowchart TB
  Config["SqlSessionFactoryBuilder
→ Configuration (XML/Annotation)"] Factory["SqlSessionFactory
→ SqlSession 생성"] Session["SqlSession
→ SQL 실행 + 매핑"] Mapper["Mapper Interface
→ type-safe SQL 호출"] DB["Database"] Config --> Factory --> Session Session --> Mapper Mapper --> DB
컴포넌트 역할
SqlSessionFactoryBuilder Configuration 파일(XML)을 읽어 SqlSessionFactory 생성[5]
SqlSessionFactory SqlSession 생성 팩토리. 애플리케이션에서 재사용되는 객체[5:1]
SqlSession SQL 실행과 Transaction 관리를 담당하는 핵심 클래스[5:2]
Mapper Interface namespace와 메서드명 매핑으로 type-safe SQL 호출

Mapper Interface와 namespace 매핑

Mapper Interface는 XML mapper의 namespace와 인터페이스 FQCN(Fully Qualified Class Name)이 일치하고, 메서드명과 SQL id가 일치하면 자동 매핑된다.[6]

// Mapper Interface
public interface BoardMapper {
    BoardDto findById(int id);  // → XML: <select id="findById" resultType="BoardDto">
}

// 호출
BoardDto board = sqlSession.getMapper(BoardMapper.class).findById(1);

Mapper Interface를 XML mapper와 연결하려면 다음 규칙을 맞춰야 한다.

항목 규칙
namespace 패키지를 포함한 Mapper Interface의 전체 이름
SQL id 매핑할 Interface 메서드 이름
최종 매핑 키 packageName.InterfaceName.methodName

MyBatis-Spring 연동

MyBatis-Spring은 Spring 애플리케이션과 MyBatis 3 사이를 연결하는 역할을 한다.[7] 핵심 Bean은 다음과 같다.

Bean 역할
DataSource DB 연결(HikariCP 등)
SqlSessionFactoryBean SqlSessionFactory를 Spring Bean으로 생성. DataSource + ConfigLocation(mybatis-config.xml) + MapperLocations(mapper XML) 설정[8]
MapperScannerConfigurer / <mybatis-spring:scan> 지정 패키지의 Mapper Interface를 스캔해 Bean으로 등록[9]
SqlSessionTemplate Thread-safe SqlSession 래퍼. Spring 트랜잭션과 연동[9:1]

다음 Java Config 예시(@MapperScan 포함)는 원문에 없는 이 page의 보충 예시이며, 원문은 XML bean 등록과 <mybatis-spring:scan>을 사용한다.[9:2]

@Configuration
@MapperScan("com.example.mapper")
public class MyBatisConfig {
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource);
        factory.setMapperLocations(new PathMatchingResourcePatternResolver()
            .getResources("classpath:mapper/**/*.xml"));
        return factory;
    }
}

공식 문서 기준 최소 연동 모델은 다음과 같다.

실패 모드

JPA와의 선택 기준

복잡한 통계 쿼리, DB 벤더 특화 기능, 다중 JOIN이 많은 도메인에서는 MyBatis가 단순·유리하고, 단순 CRUD·도메인 중심 설계에서는 JPA의 객체-관계 매핑 이점이 크다고 판단한다. 이 선택 기준 자체는 이 페이지가 위 특징 비교를 근거로 종합한 해석이며, source가 직접 제시하는 결론은 아니다.

관련

출처

테스트 질문


  1. Mybatis.md — "MyBatis는 Java Object와 SQL 문 사이의 자동 매핑을 지원하는 Persistence Framework다. 핵심은 SQL을 Java 코드 밖의 별도 파일로 분리하고, Java 객체와 SQL 파라미터/결과 사이의 매핑 작업을 대신 처리해 주는 것이다."(L31, L33), "Spring과 함께 사용할 때는 MyBatis 관련 Bean을 Spring Container에 등록해서 사용한다. 이때 Spring의 트랜잭션 기능을 함께 사용하면 @Transactional 기반으로 트랜잭션을 처리할 수 있다."(L316) ↩︎ ↩︎

  2. Mybatis.md — "MyBatis는 Hibernate나 JPA처럼 새로운 ORM 패러다임을 깊게 익혀야 하는 부담이 상대적으로 적다. 개발자가 익숙한 SQL을 그대로 사용하면서도 JDBC 코드의 반복 작업을 줄이고..." ↩︎

  3. Mybatis.md — "JDBC의 기능을 대부분 제공하는 간단한 Persistence Framework로 볼 수 있다.", "복잡한 JDBC 코드를 걷어내고 소스 코드를 간결하게 유지한다.", "수동으로 파라미터를 설정하거나 ResultSet을 객체에 직접 매핑하는 코드를 줄여 준다." ↩︎

  4. Mybatis.md — "SQL 변경이 있을 때 Java 코드를 수정하거나 다시 컴파일하지 않아도 된다."(L49), "SQL 작성, 관리, 검토를 DBA 등 다른 역할과 분리할 수 있다.", "SQL 자체를 명시적으로 관리하기 때문에 쿼리 튜닝과 검토가 비교적 쉽다." ↩︎

  5. Mybatis.md — MyBatis 3 주요 컴포넌트 표: "SqlSessionFactoryBuilder | MyBatis 설정 파일을 바탕으로 SqlSessionFactory 생성", "SqlSessionFactory | SqlSession 생성", "SqlSession | SQL 실행과 Transaction 관리를 담당하는 핵심 클래스", "SqlSessionFactory는 애플리케이션에서 재사용되는 객체다."(L228) ↩︎ ↩︎ ↩︎

  6. Mybatis.md — "Mapper Interface를 제대로 연결하려면 다음 규칙을 맞춰야 한다."(L302), "namespace | 패키지를 포함한 Mapper Interface의 전체 이름", "SQL id | 매핑할 Interface 메서드 이름"(L306-307), "문자열로 SQL ID를 직접 조합하는 방식보다 오타를 줄일 수 있고, IDE의 code assist를 활용하기 쉽다."(L278), "이 방식은 문자열 오타가 런타임 버그로 이어지기 쉽고, IDE 자동완성의 도움을 받기 어렵다."(L290) ↩︎ ↩︎

  7. Mybatis.md — "MyBatis-Spring은 Spring 애플리케이션과 MyBatis 3 사이를 연결하는 역할을 한다." ↩︎

  8. Mybatis.md — "SqlSessionFactoryBean | MyBatis 설정을 바탕으로 SqlSessionFactory를 생성하는 Spring Bean" ↩︎

  9. Mybatis.md — "SqlSessionTemplate | SQL 실행과 트랜잭션 처리를 담당하며 SqlSession 인터페이스를 구현", "SqlSessionTemplate은 Thread-safe하므로 Spring Bean으로 등록해서 공유할 수 있다.", Mapper Scanner 사용: "mapperScannerConfigurer를 사용해 지정 패키지 하위 Mapper Interface를 자동 검색 및 등록"(L427), Mapper Scanner 예시: <mybatis-spring:scan base-package="com.ssafy.*.model.mapper"/>(L448) ↩︎ ↩︎ ↩︎

  10. mybatis-spring-getting-started.md — "To use MyBatis with Spring you need at least two things defined in the Spring application context: an SqlSessionFactory and at least one mapper interface.", "If there is a Spring transaction in progress, the session will also be committed or rolled back when the transaction completes. Finally, any exceptions will be translated into Spring DataAccessExceptions." ↩︎ ↩︎ ↩︎