MyBatisでの取得処理の書き方



## 1. **基本的なマッピング**（単純なカラムとオブジェクトのフィールドの対応）


#### テーブル: `users`

```sql
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    age INT
);
```

#### エンティティ: `User.java`

```java
public class User {
    private Integer id;
    private String name;
    private Integer age;

    // Getters and Setters
}
```

#### Mapperインターフェース: `UserMapper.java`

```java
package com.example.mapper;

import com.example.model.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;

public interface UserMapper {
    List<User> selectAll();
}
```

#### Mapper XML: `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.mapper.UserMapper">
    
    <!-- 全てのユーザーを取得 -->
    <select id="selectAll" resultType="com.example.model.User">
        SELECT id, name, age
        FROM users
    </select>
    
</mapper>
```
- **`<select>`** タグの `id` 属性は、Mapperインタフェースで定義されたJavaメソッドと紐づけている
- **`<select>`** タグの `resultType` 属性は、クエリ結果が `User` クラスにマッピングされることを指定している

## 2. **複雑なマッピング**（カラム名とフィールド名が異なる場合）

#### テーブル: `users`（カラム名が異なる場合）

```sql
CREATE TABLE users (
    user_id INT AUTO_INCREMENT PRIMARY KEY,
    user_name VARCHAR(100),
    user_age INT
);
```

#### エンティティ: `User.java`

```java
public class User {
    private Integer id;
    private String name;
    private Integer age;

    // Getters and Setters
}
```


#### Mapper XML: `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.mapper.UserMapper">

    <!-- カラム名とフィールド名が異なる場合のマッピング -->
    <select id="selectAll" resultMap="UserResultMap">
        SELECT user_id, user_name, user_age
        FROM users
    </select>

    <!-- ResultMapでのカラムとフィールドのマッピング -->
    <resultMap id="UserResultMap" type="com.example.model.User">
        <id column="user_id" property="id"/>
        <result column="user_name" property="name"/>
        <result column="user_age" property="age"/>
    </resultMap>

</mapper>
```

- **`<resultMap>`** タグを使って、データベースのカラムとJavaオブジェクトのフィールドを手動でマッピングしています。
- `column`属性はSQLのカラム名、`property`属性はJavaのプロパティ名を指定しています。これにより、id, name, ageというカラムがUserオブジェクトの対応するフィールドにマッピングされます
- `id` タグは主キーを示し、`result` タグはそれ以外のカラムをマッピングします。（主キーは必須ではない）

## 3. **一対多のマッピング**

MyBatisでは、`一対多` の関係もマッピングできます。例えば、`users`テーブルと`orders`テーブルが1対多の関係にある場合です。

#### テーブル: `orders`

```sql
CREATE TABLE orders (
    order_id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT,
    order_date DATE,
    FOREIGN KEY (user_id) REFERENCES users(id)
);
```

#### エンティティ: `Order.java`

```java
public class Order {
    private Integer orderId;
    private Date orderDate;

    // Getters and Setters
}
```

#### エンティティ: `User.java`

```java
public class User {
    private Integer id;
    private String name;
    private Integer age;
    private List<Order> orders;  // ユーザーが持つ複数の注文

    // Getters and Setters
}
```

#### Mapper XML: `UserMapper.xml`

```xml
<mapper namespace="com.example.mapper.UserMapper">

    <!-- ユーザーとその注文を取得 -->
    <select id="selectUserWithOrders" resultMap="UserWithOrdersMap">
        SELECT u.id as userId, u.name as userName, u.age as userAge,
               o.order_id as orderId, o.order_date as orderDate
        FROM users u
        LEFT JOIN orders o ON u.id = o.user_id
    </select>

    <!-- ResultMapで一対多のマッピング -->
    <resultMap id="UserWithOrdersMap" type="com.example.model.User">
        <id column="userId" property="id"/>
        <result column="userName" property="name"/>
        <result column="userAge" property="age"/>
        
        <!-- 一対多の関係をマッピング -->
        <collection property="orders" ofType="com.example.model.Order">
            <id column="orderId" property="orderId"/>
            <result column="orderDate" property="orderDate"/>
        </collection>
    </resultMap>

</mapper>
```

- **`<collection>`** タグを使用して、ユーザーのオブジェクトに関連する複数の注文（`Order`オブジェクト）をマッピングしています。

## 4. **ネストされたマッピング**

MyBatisは、1つの結果セットを使用してネストされたオブジェクトもマッピングできます。例えば、あるユーザーが関連するアドレスを持っている場合です。

#### エンティティ: `Address.java`

```java
public class Address {
    private String street;
    private String city;

    // Getters and Setters
}
```

#### エンティティ: `User.java`

```java
public class User {
    private Integer id;
    private String name;
    private Integer age;
    private Address address;

    // Getters and Setters
}
```

#### Mapper XML: `UserMapper.xml`

```xml
<mapper namespace="com.example.mapper.UserMapper">

    <!-- ユーザーとその住所を取得 -->
    <select id="selectUserWithAddress" resultMap="UserWithAddressMap">
        SELECT u.id as userId, u.name as userName, u.age as userAge,
               a.street as street, a.city as city
        FROM users u
        LEFT JOIN address a ON u.id = a.user_id
    </select>

    <!-- ネストされたマッピング -->
    <resultMap id="UserWithAddressMap" type="com.example.model.User">
        <id column="userId" property="id"/>
        <result column="userName" property="name"/>
        <result column="userAge" property="age"/>
        
        <!-- Addressオブジェクトのネストされたマッピング -->
        <association property="address" javaType="com.example.model.Address">
            <result column="street" property="street"/>
            <result column="city" property="city"/>
        </association>
    </resultMap>

</mapper>
```

- **`<association>`** タグを使って、`User`オブジェクトに`Address`オブジェクトをネストしてマッピングします。

## まとめ

MyBatisのマッピング機能は、シンプルなカラムとフィールドの対応から、ネストされたオブジェクトや一対多の関係など、さまざまなデータベース構造をJavaオブジェクトにマッピングすることが可能です。