Spring + MyBatis接続設定方法

#MyBatisとは
SQLとJavaオブジェクトをマッピングすることで、JavaからのDBアクセスを間接的に行ってくれるフレームワーク。
特徴としては、SQLを設定ファイルやアノテーションに宣言的に定義することにより、
Javaで書かれたビジネスロジックからSQL自体の存在を隠蔽出来ること。

MapperインターフェイスがSQLの隠蔽をしており、MyBatisがMapperインターフェイスのメソッドとSQLを紐づけている。
その為、Javaのビジネスロジックからは、Mapperインターフェイスを呼び出すだけで紐づいているSQLを実行出来る。


#前提事項
・Eclipse　2018-09 (4.9.0)
・Windows10
・H2
・MyBatisのSQLの指定方法は「マッピングファイル」「アノテーション」の二通りあるが、
今回は「マッピングファイル」を採用する。

#初期設定
```xml:pom.xml
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.2</version>
        </dependency>
        <dependency>
		    <groupId>org.mybatis</groupId>
		    <artifactId>mybatis</artifactId>
		    <version>3.4.0</version>
		</dependency>
```

```java:MybatisTestApplication.java
@SpringBootApplication
@EnableTransactionManagement
@MapperScan("com.mybatis.test.domain")
public class MybatisTestApplication {

	//Spring Boot起動メソッド
	public static void main(String[] args) {
		SpringApplication.run(MybatisTestApplication.class, args);
	}

	//Bean定義 データソース①
	@Bean
	public DataSource dataSource() {
		return new EmbeddedDatabaseBuilder()
				.setType(EmbeddedDatabaseType.H2)
				.addDefaultScripts()
				.build();
	}

	//Bean定義 PlatformTransactionManager②
	@Bean
	public PlatformTransactionManager transactionManager() {
		return new DataSourceTransactionManager(dataSource());
	}

	//Bean定義 SqlSessionFactoryBean③
	@Bean
	public SqlSessionFactoryBean sqlSessionFactory() {
		SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
		sessionFactoryBean.setDataSource(dataSource());
		return sessionFactoryBean;
	}
```

**①データソース**
データソースのBeanを定義する。

**②PlatformTransactionManager**
トランザクションマネージャーのBeanを定義する。

**③SqlSessionFactoryBean**
SqlSessionFactoryBeanを利用して、SqlSessionFactoryが生成される。
データソースを設定して、MyBatisの処理の中でSQLを発行すると、ここで指定したデータソースから
コネクションが取得される。


#MyBatisを使ったDBアクセス
・Mapperインターフェイスの作成
・マッピングファイルの作成

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

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

//このアノテーションを付けることで、プログラムからMapperインタフェースとして認識される
@Mapper
public interface MyBatisMapper {

	//SELECTのテスト用
	public PlayerEntity selectTest(String id);

	//INSERTのテスト用
	public void insertTest(@Param("id")String id, @Param("name")String name, @Param("age")String age);

	//UPDATEのテスト用
	public void updateTest(@Param("id")String id, @Param("name")String name);

	//DELETEのテスト用
	public void deleteTest(String id);
}
```


```xml:MyBatisMapper.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">
	<!-- id属性はMapperインターフェイスに定義したメソッド名 -->
	<!-- parameterType属性はメソッド引数のクラス -->
	<!-- resultType属性は検索結果をマッピングするクラス -->
  	<select id="selectTest" parameterType="string" resultType="com.mybatis.test.domain.PlayerEntity">
  	  SELECT
  	   id,name,age
   	  FROM
   	   player
   	  WHERE
   	   id=#{id}
  	</select>

  	<insert id="insertTest" parameterType="string" >
  	  INSERT INTO
  	   player (id, name, age)
  	  VALUES
  	   (#{id}, #{name}, #{age})
  	</insert>

  	<update id="updateTest" parameterType="string">
  	 UPDATE
  	  player
  	 SET
  	  name=#{name}
  	 WHERE
  	  id=#{id}
  	</update>

  	<delete id="deleteTest" parameterType="string">
  	 DELETE FROM player WHERE id=#{id}
  	</delete>
</mapper>
```
**`XMLは、src/main/resourcesの、Mapperインタフェースを配置したフォルダと同一の場所に、
同一名で配置すること！`**
**`こうすることで、MyBatisが自動でマッピングファイルを読み込んでくれる。`**

#Mapperオブジェクトの利用
・Serviceクラス
・Controllerクラス
・Entityクラス

```java:Service
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;

	@Autowired
	PlayerRepository playerRepository;

	//SELECTを行うMapperのメソッドを呼び出す
	@Transactional
	public PlayerEntity selectTest(String id) {
		return mapper.selectTest(id);
	}

	//INSERTを行うMapperのメソッドを呼び出す
	@Transactional
	public void insertTest(String id, String name, String age) {
		mapper.insertTest(id, name, age);
	}

	//UPDATEを行うMapperのメソッドを呼び出す
	@Transactional
	public void updateTest(String id, String name) {
		mapper.updateTest(id, name);
	}

	//DELETEを行うMapperのメソッドを呼び出す
	@Transactional
	public void deleteTest(String id) {
		mapper.deleteTest(id);
	}
```

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class MybatisController {

	@Autowired
	MyBatisService myBatisService;

	@GetMapping()
	public String index(Model model) {

		PlayerEntity playerService = new PlayerEntity();
		playerService = myBatisService.selectTest("004");
		model.addAttribute("play", playerService);
		myBatisService.insertTest("010", "XXXX", "65");
		myBatisService.updateTest("004", "SSSSSS");
		myBatisService.deleteTest("001");
		return "index";
	}
以下省略
```

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

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class PlayerEntity {

	@Id
	private String id;

	private String name;
	private String age;
getter,setter省略
```

#終わりに
次はJOINしたものや、SQL文をもっと複雑にして色々といじってみたいと思います。