Spring + MyBatis接続設定方法　<テーブル結合編>

今回は2つのテーブル結合をやってみました。

#1対1の場合

##Entity

<親Entityクラス>

```java:Player.java
package com.mybatis.test.domain;

import java.util.List;

import lombok.Data;

@Data
public class Player {

	private String id;
    private String name;
    private String age;
    //子クラスの要素を定義(1対1)
    private Detail detailIds;
}
```


<子Entityクラス>

```java:Detail.java
package com.mybatis.test.domain;

import lombok.Data;

@Data
public class Detail {

	private String detailId;
    private String work;
}
```

テーブルの親子関係はdetail_idで結びつくので、Player.javaに子要素の変数を用意する。

##XML

```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.mybatis.test.domain.MyBatisMapper">
  	<select id="selectItem" resultMap="playerMap">
  	 SELECT
	  player.id
	  ,player.name
	  ,player.detail_id
	  ,detail.work
  	 FROM
  	  player
  	 JOIN
  	  detail
  	 ON
  	  player.detail_id=detail.detail_id
  	 WHERE
  	  player.id=#{id}
  	</select>

	<!-- テーブルのSELECT結果をどのようにマッピングするか指定 -->
    <resultMap id="playerMap" type="com.mybatis.test.domain.Player">
	  <id property="id" column="id" />
      <result property="name" column="name" />
      <association property="detailIds" resultMap="detailResult"/>
	</resultMap>

      <resultMap id="detailResult" type="com.mybatis.test.domain.Detail">
        <result property="detailId" column="detail_id" />
        <result property="work" column="work" />
      </resultMap>

</mapper>
```
#####テーブル結合する条件(detail_id)は必ずSQLに盛り込むこと。
検索の結果は resultMap要素で別途定義する。

resultMapでは、実際に検索結果で得たい内容（今回はPlayer）に対する結果のマッピングを行う。 
property は Javaクラス側のプロパティ（変数）を指す。 
columnはSQLのカラムを指す。

また、今回は1:1の関係なので、associationを使用する。
associationのresultMapで子要素と対応付けする。

##Interface

```java:MyBatisMapper.java
package com.mybatis.test.domain;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface MyBatisMapper {

	//JOINのテスト用
	public Player selectItem(String id);
```

##Service

```java:MyBatisService.java
package com.mybatis.test.domain;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyBatisService {

	@Autowired
	MyBatisMapper mapper;
	//JOIN
	@Transactional
	public Player selectItem(String id) {
		return mapper.selectItem(id);
	}
```

##Controller

```java:Controller
@Controller
public class MybatisController {
	@Autowired
	MyBatisService myBatisService;
		Player player = new Player();
		player = myBatisService.selectItem("002");
		model.addAttribute("playerDetail", player);
		return "index";
}
```


##Jsp

```html
	<div th:object="${playerDetail}">
		<div>
			<label><b>名前</b></label>
			<p th:text="${playerDetail.name}">
		</div>
		<div>
			<label><b>仕事</b></label>
			<p th:text="${playerDetail.detailIds.work}">
		</div>
	</div>
```


#1対多の場合

##Entity

<親Entity>

```java:Player.java
package com.mybatis.test.domain;

import java.util.List;

import lombok.Data;

@Data
public class Player {

	private String id;
    private String name;
    private String age;
    private Detail detailIds;
    //子クラスの要素定義(1対多)
    private List<Item> items;
}
```
1対多なので、フィールドにList型を定義した。

<子Entity>

```java:Item.java
package com.mybatis.test.domain;

import lombok.Data;

@Data
public class Item {

	private String id;
	private String item;
}
```

##XML

```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.mybatis.test.domain.MyBatisMapper">
      <select id="selectChoice" resultMap="itemMap">
      select
       player.id
       ,player.name
       ,item.items
      from
       player
      join
       item
      on
       player.id = item.id
      where
       player.id=#{id}
      </select>

      <!-- テーブルのSELECT結果をどのようにマッピングするか指定 -->
      <resultMap id="itemMap" type="com.mybatis.test.domain.Player">
       <id property="id" column="id" />
       <result property="name" column="name" />
       <collection property="items" ofType="com.mybatis.test.domain.Item">
       	<result property="id" column="id" />
       	<result property="item" column="items" />
       </collection>
      </resultMap>
</mapper>
```

1対多の場合は、collectionタグを使用する。(1対1の場合はassociationタグ)
collectionタグのpropertyには、子クラス(Item.java)を束ねる親クラス(Player.java)のフィールド(items)を設定する。
ofTypeで、子クラスを指定する。

ここでも、
#####テーブル結合する条件(detail_id)は必ずSQLに盛り込むこと。


interfaceやserviceなどは割愛。

##Controller

```java:MybatisController.java
@Controller
public class MybatisController {
	@Autowired
	MyBatisService myBatisService;
	@GetMapping()
	public String index(Model model) {
		Player playerChoise = myBatisService.selectChoice("002");
		//Item型のリストに詰めなおす
		List<Item> itemsList = playerChoise.getItems();
		model.addAttribute("itemsList", itemsList);
```

##Jsp

````html
	<!-- th:eachで要素を1つずつ取得する -->
	<div th:each="item : ${itemsList}">
	<p th:text="${item.item}">
	</div>
````