Spring boot+Doma2でめちゃくちゃハマった話

#経緯
最近コードをきれいにするためにStrutsからSpring bootに乗り換えました。
そのついでにDoma2を導入しようと考えて早速調べながらやってみました。
でも全然うまくいかなかったのでやり遂げて気持ち良いついでに手順を書いとこうと思います。

#環境
Springboot　2.2.6
STS4
Maven
Mysql

#手順
##1.pomにdomaを書く
実はここが一番の難所でした。
ネットに書いている通りやっているのに全くうまくいかんやんと何時間も失いました。

```pom.xml

         <dependency>
   			<groupId>org.seasar.doma.boot</groupId>
    		<artifactId>doma-spring-boot-starter</artifactId>
    		<version>1.2.1</version>
		</dependency>
		<dependency>
		    <groupId>org.seasar.doma.boot</groupId>
		    <artifactId>doma-spring-boot-core</artifactId>
		    <version>1.2.1</version>
		</dependency>
		<dependency>
		    <groupId>org.seasar.doma</groupId>
		    <artifactId>doma</artifactId>
		    <version>2.28.0</version>
		</dependency>
```

ネットにはdoma-spring-boot-starterだけでいいみたいに書いてあるんですけど、うまくいかず上記のようにすると出来ました。
全然わからないので詳しい人教えてください。

##2.application.propertiesにDBの設定記述
```application.properties
spring.datasource.url=jdbc:mysql://IPアドレス:3306/スキーマ名
spring.datasource.username=ユーザ
spring.datasource.password=パスワード
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.database=MYSQL
```

#3実際に処理を記述する
![スクリーンショット 2020-04-04 16.33.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226974/7516c061-70f4-92a8-d3d4-60eb7f8b38a5.png)


###Entityクラス
@EntityでDomaがDTOかどうかを認識しているみたいです。
このアノテーションがないとDAOでエラーが出されます。

```Sample.java
package jp.co.sample.bean;

import org.seasar.doma.Entity;

@Entity
public class Sample {
	private int id;
	private long userid;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public long getUserid() {
		return userid;
	}
	public void setUserid(long userid) {
		this.userid = userid;
	}
	
}


```

###DAO

@Daoは先ほどの@Entityと同様Doma側でDAOであると認識するために必要みたいです。

@ConfigAutowireableがないとDaoをAutowired出来ません。
ここはハマりやすいポイントみたいなのでお気をつけください。

```SampleDao.java
package jp.co.sample.dao;

import org.seasar.doma.Dao;
import org.seasar.doma.Select;
import org.seasar.doma.boot.ConfigAutowireable;

import jp.co.sample.bean.Sample;

@Dao
@ConfigAutowireable
public interface SampleDao {
	
	@Select
	public Sample select(long userid);
	
}


```

DAOはインターフェースとして宣言して実装クラスは以下のようにdomaで自動生成してくれるみたいです。
すんごい。

```SampleDaoImpl.java
package jp.co.sample.dao;

/** */
@org.springframework.stereotype.Repository()
@javax.annotation.Generated(value = { "Doma", "2.25.1" }, date = "2020-04-04T16:30:55.817+0900")
public class SampleDaoImpl extends org.seasar.doma.internal.jdbc.dao.AbstractDao implements jp.co.sample.dao.SampleDao {

    static {
        org.seasar.doma.internal.Artifact.validateVersion("2.25.1");
    }

    private static final java.lang.reflect.Method __method0 = org.seasar.doma.internal.jdbc.dao.AbstractDao.getDeclaredMethod(jp.co.sample.dao.SampleDao.class, "select", long.class);

    /**
     * @param config the config
     */
    @org.springframework.beans.factory.annotation.Autowired()
    public SampleDaoImpl(org.seasar.doma.jdbc.Config config) {
        super(config);
    }

    @Override
    public jp.co.sample.bean.Sample select(long userid) {
        entering("jp.co.sample.dao.SampleDaoImpl", "select", userid);
        try {
            org.seasar.doma.jdbc.query.SqlFileSelectQuery __query = getQueryImplementors().createSqlFileSelectQuery(__method0);
            __query.setMethod(__method0);
            __query.setConfig(__config);
            __query.setSqlFilePath("META-INF/jp/co/sample/dao/SampleDao/select.sql");
            __query.setEntityType(jp.co.sample.bean._Sample.getSingletonInternal());
            __query.addParameter("userid", long.class, userid);
            __query.setCallerClassName("jp.co.sample.dao.SampleDaoImpl");
            __query.setCallerMethodName("select");
            __query.setResultEnsured(false);
            __query.setResultMappingEnsured(false);
            __query.setFetchType(org.seasar.doma.FetchType.LAZY);
            __query.setQueryTimeout(-1);
            __query.setMaxRows(-1);
            __query.setFetchSize(-1);
            __query.setSqlLogType(org.seasar.doma.jdbc.SqlLogType.FORMATTED);
            __query.prepare();
            org.seasar.doma.jdbc.command.SelectCommand<jp.co.sample.bean.Sample> __command = getCommandImplementors().createSelectCommand(__method0, __query, new org.seasar.doma.internal.jdbc.command.EntitySingleResultHandler<jp.co.sample.bean.Sample>(jp.co.sample.bean._Sample.getSingletonInternal()));
            jp.co.sample.bean.Sample __result = __command.execute();
            __query.complete();
            exiting("jp.co.sample.dao.SampleDaoImpl", "select", __result);
            return __result;
        } catch (java.lang.RuntimeException __e) {
            throwing("jp.co.sample.dao.SampleDaoImpl", "select", __e);
            throw __e;
        }
    }

}
```

###Serivceクラス
この例ではServiceクラスはほぼ無意味になってしまいますね。


```SampleService.java
package jp.co.sample.service;

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

import jp.co.sample.bean.Sample;
import jp.co.sample.dao.SampleDao;

@Service
public class SampleService {

	@Autowired
	SampleDao dao;
	
	public Sample getSample(long userid) {
		return dao.select(userid);
	}
}

```

###Controllerクラス

```SampleController.java
package jp.co.sample.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import jp.co.sample.bean.Sample;
import jp.co.sample.service.SampleService;

@RequestMapping("/sample")
@Controller
public class SampleController {
	
	@Autowired
	SampleService service;
	
	@RequestMapping("/index")
	public String index(Model model) {
		Sample sample =  service.getSample(1234567);
		model.addAttribute("bean", sample);
		return "index";
	}
}

```

以上で処理の記述は終わりです。
Spring bootを起動してエラーが出なければ無事成功です。

よくあるエラーとして、フォルダ構成は合っているのに対象のsqlファイルがありませんと怒られることがあります。
それはプロジェクトの更新をした際にビルドパスの設定がおかしくなることがありますので以下のリンクを参考にしてみてください。
https://qiita.com/nesheep5/items/37bd1913211fcf3aebf1

#感想
本当に何時間も費やしてできると気持ちがいいですね。
Domaでこれからたくさんsql文を流していきたいと思います。
あとDomaはログにsql文が勝手に出るからすっごいいいね。
![スクリーンショット 2020-04-03 23.14.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226974/7cb476d2-3232-094c-232f-0bfdd2d07bc4.png)