스프링에서 DB 연동을 할 때 JPA와 함께 가장 많이 사용되는 기술이 바로 MyBatis(마이바티스)입니다. 실무에서는 JPA보다 훨씬 높은 비중으로 MyBatis를 사용하고 있어요. 특히 MyBatis는 SQL을 직접 작성할 수 있기 때문에 복잡한 쿼리를 다루거나 SQL 튜닝이 중요한 프로젝트에서 많이 사용됩니다. 이번 글에서는 Spring과 MyBatis가 함께 동작하는 방식과 전체 처리 흐름을 정리해보려고 합니다.
MyBatis란 무엇인가?
MyBatis는 개발자가 직접 SQL을 작성하고, 해당 SQL 결과를 자바 객체로 매핑해주는 Persistence Framework입니다. JPA처럼 자동으로 SQL을 생성해주는 ORM 방식이 아니라, 원하는 SQL을 직접 작성해서 그대로 실행하는 방식이기 때문에 DB 작업을 세밀하게 컨트롤할 수 있다는 장점이 있습니다.
- ORM이 아님 → SQL을 직접 작성
- CRUD가 명확하고 SQL 튜닝 용이
- XML 매퍼 또는 어노테이션 방식으로 SQL 작성 가능
- 복잡한 조인/서브쿼리/동적 SQL 작성 가능
Spring + MyBatis 처리 흐름

- Controller → Service : 클라이언트 요청이 들어오면 Controller는 이를 Service 계층으로 넘기고, Service는 비즈니스 로직을 처리하는 과정에서 DB 접근이 필요할 때 Repository(Mapper)를 호출합니다.
- Service → Repository(Mapper 인터페이스) 호출 : Repository 역할을 담당하는 Mapper 인터페이스의 메서드를 호출합니다. 여기서 SQL을 직접 다루지 않고, MyBatis가 Mapper 인터페이스와 XML을 이용해 대신 처리하도록 위임합니다.
- MyBatis SqlSession이 매퍼 XML을 조회 : Mapper 인터페이스가 호출되면 내부적으로 SqlSession이 해당 메서드와 매핑된 XML의 SQL 문장을 찾아 연결합니다. Mapper 인터페이스의 메서드 → <select id="findAllUsers"> 파라미터 타입과 리턴 타입까지 매칭 이 단계에서 MyBatis는 XML의 SQL을 읽어올 준비를 합니다.
- SQL 실행 : MyBatis는 XML에 정의된 SQL을 실제 DB에 실행합니다. SELECT ,INSERT ,UPDATE ,DELETE 모든 쿼리 실행이 이 단계에서 수행됩니다.
- 결과(ResultSet)를 자바 객체로 매핑 : DB에서 가져온 ResultSet은 MyBatis의 매핑 기능을 통해 DTO/VO/엔티티 형태의 자바 객체로 변환됩니다. resultType, resultMap 등을 활용해 자동 또는 수동으로 매핑됩니다.
- Service로 반환 : 매핑된 자바 객체가 Mapper → Service로 전달되고, Service는 이를 비즈니스 로직에 활용한 후 Controller로 다시 반환합니다.
MyBatis 구성 요소
- Mapper 인터페이스 : Repository 역할. 호출 가능한 메서드를 정의.
- Mapper XML : 실제 SQL이 작성되는 곳.
- SqlSession : SQL 실행 및 결과 매핑 처리.
- SqlSessionFactory : SqlSession을 생성하는 공장.
- SqlSessionTemplate : 스프링 환경에서 SqlSession을 안전하게 사용하도록 도와주는 템플릿.
이 중에서 개발자가 주로 작성하는 것은 Mapper 인터페이스 + Mapper XML 두 가지입니다.
예제 코드로 보는 MyBatis
Mapper 인터페이스
public interface MemberMapper {
Member findById(Long id);
List<Member> findAll();
void save(Member member);
}
Mapper 인터페이스는 단순히 메서드 시그니처만 가지고 있고, 실제 SQL은 XML 파일에 작성됩니다.
Mapper XML (실제 SQL)
<mapper namespace="com.example.member.MemberMapper">
<select id="findById" resultType="Member">
SELECT * FROM members WHERE id = #{id}
</select>
<select id="findAll" resultType="Member">
SELECT * FROM members
</select>
<insert id="save">
INSERT INTO members(name, email)
VALUES(#{name}, #{email})
</insert>
</mapper>
XML에서는 #{파라미터} 형태로 값 바인딩이 이루어집니다.
Service에서 사용하기
@Service
public class MemberService {
private final MemberMapper memberMapper;
public MemberService(MemberMapper memberMapper) {
this.memberMapper = memberMapper;
}
public Member findMember(Long id) {
return memberMapper.findById(id);
}
public List<Member> findMembers() {
return memberMapper.findAll();
}
}
Spring에서는 Mapper 인터페이스가 자동으로 빈으로 등록되기 때문에 Service에서 바로 주입받아 사용할 수 있습니다.
MyBatis의 장점
- SQL 직접 작성 → 복잡한 쿼리에 강함
- DB 친화적 → SQL 튜닝 가능
- XML/어노테이션 방식 둘 다 지원
- 러닝 커브 낮음
- Spring과 완벽하게 통합
특히 금융, 공공기관, 대용량 트래픽 서비스 등 정교한 SQL이 필요한 프로젝트에서 많이 사용되며, Mybatis는 JPA처럼 ORM 기반의 자동화보다는 SQL을 원하는 대로 제어하고 싶을 때 MyBatis를 사용하면 좋습니다.
'ETC. > Spring' 카테고리의 다른 글
| [Spring] 스프링 JPA란 무엇인가? - 동작 원리와 처리 흐름 정리 (0) | 2025.11.19 |
|---|---|
| [Spring] 스프링 프레임워크 MVC 처리 프로세스 - DispatcherServlet (0) | 2025.11.17 |
| [Spring] 스프링 AOP(Aspect Oriented Programming, 관점 지향 프로그래밍) (1) | 2025.11.16 |
| [Spring] 스프링 IoC(제어의 역전), DI(의존성 주입) 완벽 이해하기 (0) | 2025.11.15 |