MyBatis는 SQL 쿼리와 객체 매핑을 간소화하는 프레임워크로, XML 파일을 통해 복잡한 쿼리를 체계적으로 관리하고 재사용성을 높일 수 있습니다. 또한, resultMap
을 사용하면 데이터베이스의 결과를 객체에 유연하게 매핑할 수 있습니다.
1. MyBatis 의존성 추가
Spring Boot 프로젝트에서 MyBatis를 사용하려면 다음과 같은 의존성을 추가해야 합니다.
여기서 MyBatis 버전은 Maven Repository에서 안정화 된 버전을 사용하시거나 프로젝트 환경에 맞춰서 설정하면 됩니다.
예시에서는 편의를 위해 3.0.0으로 작성하였습니다.
1.1 Maven 설정
pom.xml
에 MyBatis Spring Boot Starter 의존성을 추가합니다.
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
1.2 Gradle 설정
build.gradle
파일에 다음을 추가합니다.
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.0'
2. MyBatis Mapper XML 설정
MyBatis의 XML 매퍼를 사용하면 SQL 쿼리를 매퍼 파일에 정의하고 매퍼 인터페이스와 연결할 수 있습니다.
2.1 매퍼 인터페이스
매퍼 인터페이스는 SQL 쿼리 호출을 위한 메서드를 정의합니다. SQL 쿼리는 XML 매퍼 파일에서 작성됩니다.
예제: UserMapper
@Mapper
public interface UserMapper {
User findById(Long id); // 사용자 조회
List<User> findAll(); // 모든 사용자 조회
void insert(User user); // 사용자 삽입
}
2.2 XML 매퍼 파일
매퍼 인터페이스의 SQL 쿼리는 XML 파일에 작성하며, 파일의 이름은 기본적으로 인터페이스 이름과 동일해야 합니다.
예제: UserMapper.xml
<?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.mapper.UserMapper">
<!-- 사용자 조회 -->
<select id="findById" parameterType="long" resultMap="userResultMap">
SELECT id, name, email FROM users WHERE id = #{id}
</select>
<!-- 모든 사용자 조회 -->
<select id="findAll" resultMap="userResultMap">
SELECT id, name, email FROM users
</select>
<!-- 사용자 삽입 -->
<insert id="insert" parameterType="com.example.domain.User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users (name, email)
VALUES (#{name}, #{email})
</insert>
<!-- 사용자 매핑 정의 -->
<resultMap id="userResultMap" type="com.example.domain.User">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="email" column="email" />
</resultMap>
</mapper>
2.3 설정 파일에서 매퍼 위치 지정
Spring Boot에서 MyBatis XML 파일을 인식하려면 application.yml
또는 application.properties
에 매퍼 경로를 설정해야 합니다.
예제: application.yml
mybatis:
mapper-locations: classpath:mappers/*.xml
3. MyBatis XML 사용 예제
3.1 데이터 조회 (단일 사용자)
매퍼 인터페이스
@Mapper
public interface UserMapper {
User findById(Long id);
}
XML 매퍼
<select id="findById" parameterType="long" resultMap="userResultMap">
SELECT id, name, email FROM users WHERE id = #{id}
</select>
서비스 및 컨트롤러
@RestController
@RequestMapping("/users")
public class UserController {
private final UserMapper userMapper;
public UserController(UserMapper userMapper) {
this.userMapper = userMapper;
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userMapper.findById(id);
if (user == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
return ResponseEntity.ok(user);
}
}
3.2 데이터 조회 (모든 사용자)
매퍼 인터페이스
@Mapper
public interface UserMapper {
List<User> findAll();
}
XML 매퍼
<select id="findAll" resultMap="userResultMap">
SELECT id, name, email FROM users
</select>
서비스에서 사용
@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userMapper.findAll();
return ResponseEntity.ok(users);
}
3.3 데이터 삽입
매퍼 인터페이스
@Mapper
public interface UserMapper {
void insert(User user);
}
XML 매퍼
<insert id="insert" parameterType="com.example.domain.User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users (name, email)
VALUES (#{name}, #{email})
</insert>
서비스 및 컨트롤러
@PostMapping
public ResponseEntity<String> createUser(@RequestBody User user) {
userMapper.insert(user);
return ResponseEntity.status(HttpStatus.CREATED).body("User created successfully!");
}
4. ResultMap을 활용한 데이터 매핑
resultMap
은 데이터베이스의 결과를 객체로 변환하는 매핑 규칙을 정의합니다. 컬럼 이름과 객체의 필드 이름이 다르거나, 관계를 매핑할 때 유용합니다.
4.1 기본 resultMap
매핑
XML 매퍼
<resultMap id="userResultMap" type="com.example.domain.User">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="email" column="email" />
</resultMap>
예제: 컬럼과 필드 이름 매핑
<resultMap id="customUserResultMap" type="com.example.domain.User">
<id property="id" column="user_id" />
<result property="fullName" column="name" />
<result property="emailAddress" column="email" />
</resultMap>
4.2 일대다 관계 매핑
사용자와 주문의 관계를 매핑
<resultMap id="userWithOrders" type="com.example.domain.User">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="email" column="email" />
<collection property="orders" ofType="com.example.domain.Order">
<id property="id" column="order_id" />
<result property="product" column="product" />
<result property="price" column="price" />
</collection>
</resultMap>
<select id="findUserWithOrders" resultMap="userWithOrders">
SELECT u.id, u.name, u.email, o.id AS order_id, o.product, o.price
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.id = #{id}
</select>
5. 결론
- XML 파일을 통해 쿼리를 체계적으로 관리할 수 있으며, 동적 SQL과
resultMap
을 활용하면 복잡한 요구사항도 손쉽게 구현할 수 있습니다.
'SpringBoot' 카테고리의 다른 글
Spring Boot: 데이터베이스 연동 (0) | 2024.11.16 |
---|---|
Spring Boot: Controller, Service, DAO, DTO (2) | 2024.11.15 |
Spring Boot: ResponseEntity를 활용한 응답 처리 (0) | 2024.11.13 |
Spring Boot: HTTP 메서드와 매핑 (1) | 2024.11.12 |
Spring Boot: RESTful API란? (0) | 2024.11.11 |