2017年度 Java 永続化フレームワークについての考察(5) Iciql

#修正履歴
1. 2017/11/14 タイトルが「永続化フレーム枠」とかいう面白ネーミングになっていたのを「フレームワーク」に修正

#前ポスト
- [2017年度 Java 永続化フレームワークについての考察(1)](http://qiita.com/shiroma_yuki/items/8d434862bba072bff264)
- [2017年度 Java 永続化フレームワークについての考察(2) Doma2](http://qiita.com/shiroma_yuki/items/d0e3b319626f4278fc6f)
- [2017年度 Java 永続化フレームワークについての推測(3) Reladomo](https://qiita.com/shiroma_yuki/items/1e3d83202afa6cf5dbef)
- [2017年度 Java 永続化フレームワークについての考察(4) jOOQ](https://qiita.com/shiroma_yuki/items/1f64cac07afc745579a5)

#前置き
隙間時間を利用して書いているので精度の甘い箇所があれば、ご指摘いただけると幸いです。
まずEOLであるものは除外。
有償の機能については検討対象に含むが、実際に使用はしません、懐の問題で。
「まぁ、たぶん明記されてなくてもPostgreならいけるだろ」ぐらいの間抜けな理由で使用DBはPostgreに固定。

#環境
- PostgreSQL 9.6.3
- [Iciql 2.1.1](http://iciql.com/)
- Java 64bit 8u144
- なんかmavenもgitも繋がらないので手動DL、もろもろ直るかも

#テーブル構成
![employeeテーブルからpostテーブルにID紐づけ](https://qiita-image-store.s3.amazonaws.com/0/48666/ec265f75-ad54-4f56-a5f8-2b460723047a.png)


#対応範囲
|ORM|Transaction|Data Model|DSL|
|:-:|:---------:|:--------:|:-:|
|○|×|×|○|
○:対応
×:非対応

#所感
- 「jOOQやQueryDSLみたいにパワフルなDSL機能はないし、Hibernateやmybatisみたいなエンタープライズ向けORMでもないよ」とのこと
- おう、ドキュメント古い
    - ![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/48666/249eba86-045a-d29d-746d-047abb517c0d.png)
    - データモデル作成ツール実行方法
        - 誤：`java -cp iciql.jar;your_db_driver.jar <parameters>`
        - 正：`java -cp iciql.jar;your_db_driver.jar com.iciql.util.GenerateModels <parameters>`
    - パラメータ
        - 誤：`-username`
        - 正：`-user`
        - 誤：`-Folder`
        - 正：`-folder`
- いきなりのpostgre character型サポート外(後述)
- エンティティ、というかデータモデルはPOJOでアノテーションベースに作る
    - 生成ツールもついてるけどあくまで補助って感じのレベル
    - 自由と引き換えの突き放しっぷり


#サンプル
##単テーブル検索
###全件検索
```Main.java
public static void main(String... args) {
    try (Db db = Db.open("jdbc:postgresql:example", "postgres", "pass")) {
        Employee e = new Employee();
        List<Employee> list = db.from(e).select();

        list.stream().forEach(em -> {
            System.out.println(em.id + ":" + em.first_name + " " + em.middle_name + " " + em.last_name);
        });
    }
}
```

###主キー検索
```Main.java
List<Employee> list = db.from(e).where(e.id).is(BigDecimal.ONE).select();
```

##テーブル結合
```Main.java
// 「com.iciql.IciqlException: ERROR: 列参照"id"は曖昧です」と言われる、joinで識別子をつけてくれないのか……
//List<EmployeePost> list = db.from(e).innerJoin(p).on(p.employee_id).is(e.id).select();
EmployeePost[] list = db.open(EmployeePostDao.class).getAllEmployeePost();

Arrays.asList(list).stream().forEach(em -> {
    System.out.println(
        em.id + ":" + em.employee_id
            + "/" + em.first_name + " " + em.middle_name + " " + em.last_name + " " + em.name);
    });
```
```EmployeePostDao.java
public interface EmployeePostDao extends Dao {
    // なんかここでは配列のみでListは許容されない
    @SqlQuery("SELECT e.id AS employee_id, e.first_name, e.middle_name, e.last_name, p.id AS id, p.name FROM employee AS e INNER JOIN post AS p ON e.id = p.employee_id")
    EmployeePost[] getAllEmployeePost();
}
```
```EmployeePost.java
@Iciql.IQSchema("public")
@Iciql.IQIndex(name="Id", type= Iciql.IndexType.UNIQUE, value={ "id" })
public class EmployeePost {

    @Iciql.IQColumn(primaryKey=true, nullable=false, defaultValue="0", name = "id")
    public BigDecimal id;
    public String first_name;
    public String last_name;
    public String middle_name;
    @Iciql.IQColumn(nullable=false, defaultValue="0")
    public BigDecimal employee_id;
    public String name;

    public EmployeePost() {}
}
```

##生成データモデル
実に簡素なものが出てきます。
character(60)で設定したカラムがbpcharでunsupportedになってるあたりにつらみ。

```Employee.java
@IQSchema("public")
@IQTable(name="employee")
@IQIndex(name="Id", type=IndexType.UNIQUE, value={ "id" })
public class Employee implements Serializable {

	private static final long serialVersionUID = 1L;

	@IQColumn(primaryKey=true, nullable=false, defaultValue="0")
	public BigDecimal id;

	// unsupported type bpchar
	public Object first_name;

	// unsupported type bpchar
	public Object last_name;

	// unsupported type bpchar
	public Object middle_name;

	public Employee() {
	}
}
```

#要点
- ライブラリ自身の軽さ重視で最低限の機能のみを提供
- POJOだったりインターフェイスのみの定義だったり、継承の複雑さは一切排除する方針

#ハマったポイント
公式のドキュメントが違ってるのでソースを信じる。

#後ポスト
まだない。

#参考記事
- [Iciql - A model-based database access wrapper for JDBC](http://iciql.com/)