Spring BootでMyBatisを利用する方法

# Spring BootでMyBatisを利用する方法

## はじめに

MyBatisは、Javaの永続化フレームワークの1つで、SQLとJavaコードを分離して管理できる特徴があります。この記事では、Spring BootプロジェクトでMyBatisを利用する方法について説明します。

## 1. プロジェクトのセットアップ

### 依存関係の追加

`build.gradle`（Gradleの場合）：

```gradle
dependencies {
    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
    implementation 'org.postgresql:postgresql:42.7.2'  // PostgreSQLの場合
    // または
    implementation 'com.mysql:mysql-connector-j:8.3.0'  // MySQLの場合
}
```

`pom.xml`（Mavenの場合）：

```xml
<dependencies>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>3.0.3</version>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.7.2</version>
    </dependency>
    <!-- または -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <version>8.3.0</version>
    </dependency>
</dependencies>
```

### アプリケーション設定

`application.yml`：

```yaml
spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/mydatabase
    username: postgres
    password: password
    driver-class-name: org.postgresql.Driver

mybatis:
  mapper-locations: classpath:mapper/**/*.xml
  type-aliases-package: com.example.project.model
  configuration:
    map-underscore-to-camel-case: true
```

## 2. エンティティの作成

```java
public class User {
    private Long id;
    private String name;
    private String email;
    private LocalDateTime createdAt;
    
    // getters, setters, constructor
}
```

## 3. Mapperインターフェースの作成

```java
@Mapper
public interface UserMapper {
    List<User> findAll();
    User findById(Long id);
    void insert(User user);
    void update(User user);
    void delete(Long id);
}
```

## 4. XMLマッパーファイルの作成

`src/main/resources/mapper/UserMapper.xml`：

```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.project.mapper.UserMapper">
    
    <resultMap id="userResultMap" type="User">
        <id property="id" column="id" />
        <result property="name" column="name" />
        <result property="email" column="email" />
        <result property="createdAt" column="created_at" />
    </resultMap>

    <select id="findAll" resultMap="userResultMap">
        SELECT * FROM users
    </select>

    <select id="findById" resultMap="userResultMap">
        SELECT * FROM users WHERE id = #{id}
    </select>

    <insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO users (name, email, created_at)
        VALUES (#{name}, #{email}, #{createdAt})
    </insert>

    <update id="update" parameterType="User">
        UPDATE users
        SET name = #{name},
            email = #{email}
        WHERE id = #{id}
    </update>

    <delete id="delete">
        DELETE FROM users WHERE id = #{id}
    </delete>
</mapper>
```

## 5. サービスクラスの実装

```java
@Service
@Transactional
public class UserService {
    private final UserMapper userMapper;

    @Autowired
    public UserService(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    public List<User> findAll() {
        return userMapper.findAll();
    }

    public User findById(Long id) {
        return userMapper.findById(id);
    }

    public void create(User user) {
        user.setCreatedAt(LocalDateTime.now());
        userMapper.insert(user);
    }

    public void update(User user) {
        userMapper.update(user);
    }

    public void delete(Long id) {
        userMapper.delete(id);
    }
}
```

## 6. コントローラーの実装

```java
@RestController
@RequestMapping("/api/users")
public class UserController {
    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping
    public List<User> getAllUsers() {
        return userService.findAll();
    }

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }

    @PostMapping
    public void createUser(@RequestBody User user) {
        userService.create(user);
    }

    @PutMapping("/{id}")
    public void updateUser(@PathVariable Long id, @RequestBody User user) {
        user.setId(id);
        userService.update(user);
    }

    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.delete(id);
    }
}
```

## 7. 動的SQLの使用例

```xml
<select id="searchUsers" resultMap="userResultMap">
    SELECT * FROM users
    <where>
        <if test="name != null and name != ''">
            AND name LIKE CONCAT('%', #{name}, '%')
        </if>
        <if test="email != null and email != ''">
            AND email LIKE CONCAT('%', #{email}, '%')
        </if>
    </where>
    ORDER BY created_at DESC
</select>
```

対応するMapperインターフェース：

```java
@Mapper
public interface UserMapper {
    List<User> searchUsers(@Param("name") String name, @Param("email") String email);
}
```

## まとめ

この記事では、Spring BootでMyBatisを利用する基本的な方法について説明しました。主なポイントは以下の通りです：

1. プロジェクトのセットアップと依存関係の追加
2. エンティティとMapperインターフェースの作成
3. XMLマッパーファイルの作成とSQLの定義
4. サービスクラスとコントローラーの実装
5. 動的SQLの使用例

MyBatisを使用することで、SQLとJavaコードを分離して管理でき、より柔軟なデータベース操作が可能になります。

## 参考資料

- [MyBatis公式ドキュメント](https://mybatis.org/mybatis-3/ja/index.html)
- [MyBatis Spring Boot Starter](https://github.com/mybatis/spring-boot-starter)
- [Spring Boot公式ドキュメント](https://spring.io/projects/spring-boot)