SIerに入って８年ぐらい経ったのでいろいろ棚卸しをしてみる。【vol.002 JDBC】

## 出会い
２０１１年に現在の部署に新卒で配属されて、翌２０１２年の年明けに製造業系のPOCシステム開発にアサインされた。
Java6、[Struts](https://www.atmarkit.co.jp/ait/articles/0402/13/news095.html)と今となっては懐かしい技術での開発で、自分にとっては初のコーディングPJでもある。
[O/Rマッパー](https://thinkit.co.jp/free/article/0606/13/1)は、当時の[iBATIS](https://codezine.jp/article/detail/1289)でSqlMapConfigにDBへの接続設定やらSQL、マッピング定義を書く。

そんな案件でJDBCと出会った。

## JDBCとは

>「JDBC（Java Data Base Connectivity）」はJavaからデータベースを呼び出すためのＡＰＩです。
>正確には直接Javaがデータベースを操作するのではなく、「JDBCドライバ」を介してデータベースを操作することになります。
>Javaからは「JDBCドライバ」に対して命令を出し、JDBCドライバがその命令に従いデータベースで処理を実行し、そしてその結果を返します。
[JDBC 1章　JDBC API 1.1. JDBCドライバ](https://www.techscore.com/tech/Java/JavaEE/JDBC/1/)

- 基本的にJavaからDBに対してCRUDのSQLを投げるやつである。
- Insert、Update、Deleteしてデータ操作したり、Selectでデータ取得したりする。
- SQLは、Javaのクラスに書くのでその点、密結合である。
- SQLをゴリゴリとクラスに書くあたり、C#の[Dapper](https://webbibouroku.com/Blog/Article/dapper)と親しいものを感じる。
- クラスへのマッピングは自動でやってくれないので、ResultSetから一つ一つ取り出してSetしてあげる手のかかる子である。
- ドライバー（com.xxx.jdbc.Driver）を差し替えるだけで、各DB製品（Oracle, Postgres, etc）に対応する。

## 振り返ってみて

- 今どきJavaでO/Rマッパー（[JPA](https://terasolunaorg.github.io/guideline/public_review/ArchitectureInDetail/DataAccessJpa.html#spring-data-jpa)、[Hibernate](https://www.techscore.com/tech/Java/Others/Hibernate/index/)、[MyBatis](http://www.mybatis.org/mybatis-3/ja/index.html)）を使わないPJなんてないだろうことを考えると、非常に原始的な仕組みなのでいい出会いだったと思う。
- 以下の処理を自分でコーディングするので、DBアクセス周りの仕組みを理解するには良い。
 - DBにコネクションつなぐ。
 - トランザクションを張る。
 - SQLを発行する。
 - 結果をクラスへマッピングする。 
- 最近の若手だといきなりJPAで、以下の環境でコーディングしたりする人もいると思う。
  - DBへの接続やトランザクション周りは共通クラスで隠蔽されている。
  - SQLは自動発行される。
  - 自動でクラスにマッピングしてくれる。
- 便利になった分、仕組みを理解せずに動くもの作れる。
- 仕組みを理解していないと、DBアクセス周りで障害が起きたときに対応できない。
- と思うので、若手のOJTの時はいろいろ説明するようにしている。
- もはや大規模な開発で使用するには生産性が悪すぎるので、PJで本番コードに乗るもので採用しようとは思わない。
- ただ、新人研修とか配属後のOJTでは簡単なツール作りとかで使用するといいかもしれない。

## どんなところで使ったのか。

- 初めて使ったときは、わざわざO/Rマッパー（iBatis）をプロジェクトに設定するほどじゃない簡単なツール作りで使った。
- テキストファイルをReadして、そのReadした内容を使ってDB操作をするような簡単なツール。
- その後、何年か後にUnitテスト周りのDBアクセスで作り込みをするときに使った。
- 当時出ていたDBUnitとかのライブラリーだとかゆいところに手が届かず、ゴリゴリとコーディングした気がする。

## サンプルで実装してみる。

```java

package sample.jdbc.dao;

import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import sample.jdbc.model.Worker;

public class SampleDao {

	public static SampleDao instance = new SampleDao();

	private SampleDao () {

	}

	public List<Worker> select() throws SQLException {

		var connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres", "postgres", "postgres");
		var statment = connection.createStatement();

        var sql = "select * from worker";
        var resultSet = statment.executeQuery(sql);

        var workerList = new ArrayList<Worker>();

        while(resultSet.next()){

            var worker = new Worker();

            worker.setId(resultSet.getString("id"));
            worker.setName(resultSet.getString("name"));
            worker.setAge(String.valueOf(resultSet.getInt("age")));
            worker.setDepartment(resultSet.getString("department"));

            workerList.add(worker);
        }

        resultSet.close();
        statment.close();
        connection.close();

        return workerList;
	}

	public int insert() throws SQLException {

		var connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres", "postgres", "postgres");
		connection.setAutoCommit(false);

		var statment = connection.createStatement();

        var sql = "insert into worker values ('0001', 'k.jarrett', 73, 'music');";

        var resultCount = statment.executeUpdate(sql);

        connection.commit();
        statment.close();
        connection.close();

        return resultCount;
	}

	public int update() throws SQLException {

		var connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres", "postgres", "postgres");
		connection.setAutoCommit(false);

		var statment = connection.createStatement();

        var sql = "update worker set age = 74 where id = '0001'";

        var resultCount = statment.executeUpdate(sql);

        connection.commit();
        statment.close();
        connection.close();

        return resultCount;
	}

	public int delete() throws SQLException {

		var connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres", "postgres", "postgres");
		connection.setAutoCommit(false);

		var statment = connection.createStatement();

        var sql = "delete from worker where id = '0001'";

        var resultCount = statment.executeUpdate(sql);

        connection.commit();
        statment.close();
        connection.close();

        return resultCount;
	}
}

```

サンプルプロジェクトごとGitHubにプッシュしています。
https://github.com/TsJazz27Sumin/jdbcSample/tree/master/src/sample/jdbc