MyBatis 개념과 구조
MyBatis는 Java 애플리케이션에서 데이터베이스와 상호작용할 때 SQL 쿼리를 쉽게 관리하고 매핑해주는 SQL Mapper 프레임워크이다.
MyBatis는 ORM(Object Relational Mapping)과는 다르게, SQL을 직접 작성하면서 객체와 관계형 데이터베이스 간의 매핑을 돕는 도구이다.
이 글을 통해 MyBatis의 개념과 주요 구조에 대해 이해해보자.
MyBatis란?
MyBatis는 SQL 쿼리를 직접 작성하고 관리할 수 있는 SQL Mapper 프레임워크이다.
일반적인 ORM 프레임워크와 달리, 직접적인 SQL 제어가 가능하며, SQL과 자바 객체를 매핑하는 기능을 제공한다.
개발자는 복잡한 SQL 로직을 쉽게 처리하고, 객체와 데이터베이스 간의 변환 작업을 단순화할 수 있다.
MyBatis는 XML 또는 어노테이션 기반으로 SQL을 정의하며, 자바 객체와 데이터베이스 간의 매핑 작업을 자동화해 준다. 이를 통해 복잡한 SQL 로직을 유지하면서도, 객체 지향 설계를 유지할 수 있다.
MyBatis의 장단점
장점:
직접적인 SQL 제어:
MyBatis는 SQL 쿼리를 직접 작성할 수 있어, 복잡한 쿼리나 고성능을 요구하는 상황에서 더 유연하게 대처할 수 있다.유연한 매핑:
XML이나 어노테이션을 통해 자바 객체와 SQL 간의 매핑을 유연하게 설정할 수 있어, 다양한 데이터베이스 스키마를 처리하는 데 유리하다.비즈니스 로직과 SQL 분리:
SQL을 XML 파일에 별도로 작성함으로써, 비즈니스 로직과 데이터베이스 접근 로직을 명확히 분리할 수 있다.
단점:
복잡한 SQL 유지 관리:
SQL을 직접 작성해야 하기 때문에, 쿼리가 복잡해지면 이를 관리하는 데 어려움이 있을 수 있다.자동화 부족:
ORM 프레임워크에 비해, 객체와 데이터베이스 간의 매핑 작업이 자동화되지 않아 추가적인 설정이 필요하다.
MyBatis 예시
1
2
3
4
5
6
7
8
9
10
11
public interface UserMapper {
// 사용자 정보를 조회하는 SQL 쿼리 매핑
@Select("SELECT * FROM users WHERE id = #{id}")
User getUserById(int id);
// 사용자 정보를 삽입하는 SQL 쿼리 매핑
@Insert("INSERT INTO users(username, email) VALUES(#{username}, #{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void insertUser(User user);
}
위 예시에서, UserMapper 인터페이스는 MyBatis를 사용하여 SQL 쿼리를 매핑하는 방법을 보여준다. @Select와 @Insert 어노테이션을 사용하여 SQL 쿼리를 직접 정의하고, 자바 객체와 데이터베이스 간의 매핑을 수행한다.
MyBatis의 구조?
MyBatis는 크게 세 가지 주요 컴포넌트로 구성된다.
- SQL Mapper: SQL 쿼리와 자바 객체를 매핑하는 설정 파일(XML 또는 어노테이션 기반)
- Mapper Interface: SQL 쿼리와 자바 메서드를 연결하는 인터페이스
- Session: 데이터베이스와의 연결을 관리하며, 쿼리를 실행하는 역할을 담당
(1) ~ (4) 응용 프로그램 시작시 수행되는 프로세스
1:. SqlSessionFactoryBean은 SqlSessionFactoryBuilder를 위해 SqlSessionFactory를 빌드하도록 요청합니다.
2:. 응용 프로그램은 SqlSessionFactoryBuilder를 사용하여 빌드된 SqlSessionFactory에서 SqlSession을 가져옵니다.
3:. SqlSessionFactoryBuilder는 MyBatis 구성 파일의 정의에 따라 SqlSessionFactory를 생성합니다. 따라서 생성된 SqlSessionFactory는 Spring DI 컨테이너에 의해 저장됩니다.
4:. MapperFactoryBean은 안전한 SqlSession(SqlSessionTemplate) 및 스레드 안전 매퍼 개체(Mapper 인터페이스의 프록시 객체)를 생성합니 다. 따라서 생성되는 매퍼 객체는 스프링 DI 컨테이너에 의해 저장되며 서비스 클래스 등에 DI가 적용됩니다. 매퍼 개체는 안전한 SqlSession(SqlSessionTemplate)을 사용하여 스레드 안전 구현을 제공합니다.
(5) ~ (11) 클라이언트의 각 요청에 대해 수행되는 프로세스
5:. 클라이언트가 응용 프로그램에 대한 프로세스를 요청합니다.
6:. 애플리케이션(서비스)은 DI 컨테이너에서 주입한 매퍼 개체(매퍼 인터페이스
7:. 매퍼 객체는 호출된 메소드에 해당하는 SqlSession (SqlSessionTemplate ) 메서드를 호출합니다.
8:. SqlSession (SqlSessionTemplate )은 프록시 사용 및 안전한 SqlSession 메서드를 호출합니다.
9:. 프록시 사용 및 스레드 안전 SqlSession은 트랜잭션에 할당된 MyBatis3 표준 SqlSession을 사용합니다. 트랜잭션에 할당된 SqlSession이 존재하지 않는 경우 SqlSessionFactory 메서드를 호출하여 표준 MyBatis3의 SqlSession을 가져옵니다.
10:. SqlSessionFactory는 MyBatis3 표준 SqlSession을 반환합니다. 반환된 MyBatis3 표준 SqlSession이 트랜잭션에 할당되기 때문에 동일한 트랜잭션 내에 있는 경우 새 SqlSession을 생성하지 않고 동일한 SqlSession을 사용합니다.on 메서드를 호출하고 SQL 실행을 요청합니다.
11:. MyBatis3 표준 SqlSession은 매핑 파일에서 실행할 SQL을 가져와 실행합니다.
MyBatis는 이러한 구조를 통해 데이터베이스와의 상호작용을 쉽게 관리하고, 자바 객체와 SQL 쿼리를 유연하게 매핑할 수 있다.
MyBatis의 특징 정리
SQL 중심의 제어:
MyBatis는 SQL을 직접 제어할 수 있어 복잡한 데이터베이스 로직을 유연하게 처리할 수 있다.매핑 유연성:
자바 객체와 SQL 간의 매핑 작업을 XML이나 어노테이션으로 처리할 수 있어, 다양한 데이터베이스 환경에 대응 가능하다.성능 최적화:
MyBatis는 성능을 최적화할 수 있는 세밀한 제어가 가능하지만, SQL 작성에 따른 관리 비용이 증가할 수 있다.
XML Mapper 파일 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.UserMapper">
<!-- 사용자 정보를 ID로 조회하는 쿼리 -->
<select id="getUserById" parameterType="int" resultType="com.example.User">
SELECT * FROM users WHERE id = #{id}
</select>
<!-- 사용자 정보를 삽입하는 쿼리 -->
<insert id="insertUser" parameterType="com.example.User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users (username, email)
VALUES (#{username}, #{email})
</insert>
<!-- 사용자 정보를 업데이트하는 쿼리 -->
<update id="updateUser" parameterType="com.example.User">
UPDATE users
SET username = #{username}, email = #{email}
WHERE id = #{id}
</update>
<!-- 사용자 정보를 삭제하는 쿼리 -->
<delete id="deleteUser" parameterType="int">
DELETE FROM users WHERE id = #{id}
</delete>
</mapper>
Mapper와 연동하는 자바 코드 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import org.apache.ibatis.session.SqlSession;
public class UserService {
private SqlSession sqlSession;
public UserService(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}
// 사용자 정보 조회
public User getUserById(int id) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.getUserById(id);
}
// 사용자 정보 삽입
public void insertUser(User user) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.insertUser(user);
}
// 사용자 정보 업데이트
public void updateUser(User user) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateUser(user);
}
// 사용자 정보 삭제
public void deleteUser(int id) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser(id);
}
}
MyBatis 설정 파일 예시 (mybatis-config.xml)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydb" />
<property name="username" value="root" />
<property name="password" value="password" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/example/UserMapper.xml" />
</mappers>
</configuration>
결론
MyBatis는 SQL을 직접 제어하면서 객체 지향 설계를 유지하고자 할 때 매우 유용한 도구이다.
ORM보다 더 세밀한 제어가 가능하며, SQL을 직접 작성하고 유지해야 한다는 점에서 유연성이 있다.
데이터베이스와의 상호작용에서 높은 성능과 복잡한 쿼리가 필요한 상황에 MyBatis는 훌륭한 선택이 될 수 있다.