들어가며
Mybatis는 자바 ORM(Object Relational Mapping) 프레임워크 중 하나로, SQL 쿼리문을 XML 혹은 어노테이션으로 관리하면서 자바 객체와 데이터베이스 사이의 매핑을 쉽게 도와주는 도구이다.
Mybatis의 동작 원리를 단계적으로 살펴보자.
1. 설정 파일 로딩
Mybatis는 mybatis-config.xml 설정 파일을 통해 시작된다. 이 파일에서 데이터베이스 연결 정보, 트랜잭션 관리 방식, 매퍼 파일 위치 등을 설정할 수 있다.
설정 파일을 읽어들여 SqlSessionFactory를 생성하는 건데, 이 객체는 세션을 생성하는 공장 역할을 한다. 이 과정에서 Mybatis는 설정 파일의 정보를 기반으로 내부적으로 필요한 준비를 마친다고 볼 수 있다.
2. SqlSession 생성
데이터베이스에 대한 모든 작업을 진행하는 객체로, SqlSessionFactory를 통해 생성된다. 이 세션을 통해 SQL을 실행하거나, 트랜잭션을 관리할 수 있다.
SqlSession 특징으로는 일반적으로 요청이 들어올 때마다 생성하고, 요청 처리가 끝나면 닫는 단일 사용 객체이다. 이렇게 사용하는 이유는 데이터베이스 연결 리소스를 효율적으로 관리하기 위함이다.
3. 매퍼 파일 실행
매퍼 파일이란 SQL 쿼리문과 자바 객체를 연결시키는 설정 파일이다. XML 형식으로 작성되거나, 어노테이션을 사용해서 인터페이스에 직접 쿼리를 정의할 수 있다.
이러한 매퍼 파일은 SqlSession을 통해 특정 매퍼를 실행시키는데, 이때 실행하고자 하는 SQL 문에 해당하는 매퍼의 id를 지정하여 호출할 수 있다.
4. SQL 실행 및 결과 반환
SqlSession을 통해 실행된 SQL은 데이터베이스에 전달돼서 실행되고, 그 결과가 Mybatis에 의해 반환된다.
실행 결과는 결과 매핑 설정에 따라 자바 객체로 변환되어 반환되는데, 이 과정에서 복잡한 결과도 쉽게 객체에 매핑할 수 있게 도와주는게 Mybatis이고 이때 설정하는 것이 resultType, parameterType이다.
5. 세션 종료
데이터베이스 작업이 끝나면, SqlSession을 닫아야 하는건 너무나도 기본적인 사실이다.
Mybatis를 사용할 때 자동으로 세션을 관리해주는 기능에 대해 조금 더 구체적으로 정리하자면
Mybatis에서는 세션 관리를 위해 SqlSession 객체를 사용하지만, 이 객체의 생성과 소멸(종료)은 개발자가 직접 관리할 수도 있고, 특정 환경이나 프레임워크를 사용해서 자동으로 관리되게 할 수도 있다.
예를 들어, 스프링 프레임워크와 Mybatis를 통합해서 사용하는 경우, 스프링의 트랜잭션 관리 기능을 이용하면 Mybatis의 SqlSession을 자동으로 열고 닫아주는 관리가 가능하다. 스프링 트랜잭션 관리자가 현재 실행 중인 트랜잭션의 컨텍스트에 따라 SqlSession을 열고, 작업이 끝나면 자동으로 세션을 닫아주거나, 예외가 발생했을 때 롤백 처리를 해줄 수 있다.
스프링 설정 파일에 트랜잭션 관리자 설정
<!-- MyBatis SqlSessionFactoryBean 설정 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 생략: 추가 설정 -->
</bean>
<!-- 데이터 소스 설정 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 생략: 데이터베이스 연결 정보 설정 -->
</bean>
<!-- 트랜잭션 매니저 설정 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- @Transactional 어노테이션을 사용하기 위한 설정 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
서비스 계층에서 @Transactional 사용
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.mybatis.spring.SqlSessionTemplate;
@Service
public class MyService {
private final SqlSessionTemplate sqlSessionTemplate;
@Autowired
public MyService(SqlSessionTemplate sqlSessionTemplate) {
this.sqlSessionTemplate = sqlSessionTemplate;
}
@Transactional
public void someDatabaseOperation() {
// 매퍼 인터페이스를 사용하여 SQL 실행
MyMapper myMapper = sqlSessionTemplate.getMapper(MyMapper.class);
myMapper.insertSomething();
// 필요한 경우 여러 데이터베이스 작업을 수행
// 예외가 발생하면, 자동으로 롤백됨
}
}
스프링 버전에 따라서는 <tx:annotation-driven transaction-manager="transactionManager"/> 설정을 XML에 명시적으로 추가하지 않아도 된다. 특히, 스프링 부트를 사용하는 경우나 스프링의 자동 설정 기능을 활용할 때는 이 설정이 자동으로 적용된다.
Spring Boot에서는 @EnableTransactionManagement 어노테이션 또는 자동 설정을 통해 선언적 트랜잭션 관리를 쉽게 활성화할 수 있다.
스프링 부트를 사용한다면, 대부분의 경우 스프링 부트의 자동 설정이 트랜잭션 관리자를 포함하여 필요한 설정을 자동으로 처리해 줘서, 별도로 XML 파일이나 자바 설정 파일에 트랜잭션 관리 관련 설정을 추가할 필요가 없다.
하지만, 스프링 같은 프레임워크 없이 순수 Mybatis만 사용하는 경우에는 개발자가 SqlSession을 직접 열고 닫아주는 코드를 작성해야한다. 이 경우에는 보통 try-with-resources 구문을 사용해서 SqlSession이 자동으로 종료되도록 처리한다.
try (SqlSession session = sqlSessionFactory.openSession()) {
// 데이터베이스 작업 수행
}
'Spring' 카테고리의 다른 글
Mybatis를 왜사용하는걸까? Mybatis 장단점 정리 (0) | 2022.04.14 |
---|---|
Spring - 컨트롤러에 POST mapping url이 정확한데도 404 에러가 뜨는 이유 - Java Reflection (0) | 2022.02.23 |
Spring - RequestParam 사용법 (0) | 2022.01.26 |
Spring - An illegal reflective access operation has occurred Illegal reflective access by org.apache.ibatis.reflection.Reflector (0) | 2022.01.21 |
Spring - Json 반환 (0) | 2022.01.20 |