S2Daoを利用出来るようになるまでの初期設定

S2Daoの初期設定についてあまり記事が見当たらず、少し苦戦したので今後の自分のためにメモしておきます。

## 実行環境

* Java 1.8
* Seasar 2.4.46
* SAStruts 1.0.4-sp9
* s2-dao-tiger 1.0.49
* MySQL 8.0.13

## ゴール

S2Daoを利用したDaoインターフェースが自動バインディングされてSQL実行されること。

## DB初期設定

```sql:balanceテーブルにデータを格納
mysql> select * from sastrutsdb.balance;
+----+--------------+--------+---------------------+------------+
| id | name         | amount | created_at          | updated_at |
+----+--------------+--------+---------------------+------------+
|  1 | 田中太郎     |  10000 | 2019-05-03 19:25:33 | NULL       |
|  2 | 佐藤花子     |  20000 | 2019-05-03 23:48:40 | NULL       |
+----+--------------+--------+---------------------+------------+
2 rows in set (0.00 sec)
```

## pom&diconファイル設定

### pomファイル設定

mysql-connector-java-8.0.16.jarとs2-dao-1.0.49.jarをダウンロード

```java:pom.xml
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>8.0.16</version>
        </dependency>
        <dependency>
          <groupId>org.seasar.dao</groupId>
          <artifactId>s2-dao-tiger</artifactId>
          <version>1.0.49</version>
        </dependency>
```

プロジェクトをMaven Cleanする。

<font color="DarkSalmon">※WEB-INF/libに対象jarが存在することを確認
pomにcopy-dependenciesを設定することで自動copyされる</font>

### diconファイル設定

daoインターフェースをコンテナにコンポーネント登録するためのdiconファイルの作成
includeしているdao.diconは、s2-dao-1.0.49.jar内に存在するdiconファイル

addClassPatternにコンポーネント登録するdaoインターフェースのクラスを指定する。

```java:MySQL.dicon（ファイル名はなんでもOK）
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components>
    <include path="dao.dicon"/>

    <component name="traceInterceptor" class="org.seasar.framework.aop.interceptors.TraceInterceptor"/>

    <component class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
      <property name="autoNaming">
        <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
      </property>
      <initMethod name="addClassPattern">
        <arg>"org.seasar.sastruts.example.dao"</arg>
        <arg>".*Dao"</arg>
      </initMethod>
    </component>

    <component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
      <property name="interceptor">dao.interceptor</property>
      <initMethod name="addClassPattern">
        <arg>"org.seasar.sastruts.example.dao"</arg>
        <arg>".*Dao"</arg>
      </initMethod>
    </component>

</components>
```

app.diconに上記で作成したdiconファイルを指定

```java:app.dicon
  <include path="MySQL.dicon"/>
```

jdbc.diconにmysqlの設定とS2Daoのコンポーネント登録
ユーザー名とパスワードは適当に設定している

```java:jdbc.dicon
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
	"http://www.seasar.org/dtd/components24.dtd">
<components namespace="jdbc">
	<include path="jta.dicon"/>

    <component name="resultSetFactory" class="org.seasar.dao.pager.PagerResultSetFactoryWrapper">
      <arg>
        <component class="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/>
      </arg>
      <property name="useScrollCursor">true</property>
    </component>
    <component class="org.seasar.extension.jdbc.impl.ConfigurableStatementFactory">
      <arg>
        <component class="org.seasar.dao.pager.PagerStatementFactory"/>
      </arg>
      <property name="fetchSize">100</property>
    </component>

	<component name="xaDataSource"
		class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
		<property name="driverClassName">
			"com.mysql.cj.jdbc.Driver"
		</property>
		<property name="URL">
			"jdbc:mysql://localhost:3306/sastrutsdb?characterEncoding=UTF-8&amp;characterSetResults=UTF-8"
		</property>
		<property name="user">"sa"</property>
		<property name="password">"password"</property>
	</component>

	<component name="connectionPool"
		class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
		<property name="timeout">600</property>
		<property name="maxPoolSize">10</property>
		<property name="allowLocalTx">true</property>
		<destroyMethod name="close"/>
	</component>

	<component name="DataSource"
		class="org.seasar.extension.dbcp.impl.DataSourceImpl"
	/>

</components>
```


これで設定は終わりです。
あとは実装していきます。

## 実装

### Entity作成

```java:Balance
@Entity
@Table(name = "sample")
public class Balance {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	public int id;

	@Column(name = "amount", nullable = false, unique = false)
	public long amount;
	
	@Column(name = "name", nullable = false, unique = false)
	public String name;

	@Column(name = "created_at", nullable = false, unique = false)
	@Temporal(TemporalType.DATE)
	public Date createdAt;

	@Column(name = "updated_at", nullable = true, unique = false)
	@Temporal(TemporalType.DATE)
	public Date updatedAt;

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("id:").append(id);
		sb.append("name:").append(name);
		sb.append("created_ad:").append(createdAt);
		sb.append("updated_ad:").append(updatedAt);
		return sb.toString();
	}
}
```

### Action作成

```java:BalanceAction
public class BalanceAction {

	@Binding
	BalanceService balanceService;

	@Execute(validator=false)
	public String index() {
		List<Balance> balanceList = balanceService.findAll();
		System.out.println("BALANCE_SIZE:" + balanceList.size());
		StringBuilder responseText = new StringBuilder();

		for (Balance balance : balanceList) {
			responseText.append(balance.toString() + "\r\n");
		}
		ResponseUtil.write(responseText.toString(), "text/html", "UTF-8");
		return null;
	}
}
```


### Service作成

ここでDaoファイルをBinding

```java:BalanceService
public class BalanceService {

	@Binding
	BalanceDao balanceDao;

	public List<Balance> findAll() {
		return balanceDao.findAll();
	}
}
```

### Daoインターフェース作成

```java:BalanceDao
@S2Dao(bean = Balance.class)
public interface BalanceDao {
	public List<Balance> findAll();
}
```

## 実行

```shell
$ curl "localhost:8080/sastruts/balance/"
id:1name:田中太郎created_ad:2019-05-03 19:25:33.0updated_ad:null
id:2name:佐藤花子created_ad:2019-05-03 23:48:40.0updated_ad:null
```

無事データ取得できました。

## 参考
[Seasar2 S2Dao 入門](http://snowhiro.web.fc2.com/seasar2/Seasar2_04_S2Dao_02.html)
[S2Daoリファレンス](http://s2dao.seasar.org/ja/s2dao.html)