ICIQL導入をしてみる

## ICIQLについて

### ICIQLとは
　ICIQLとはO/Rマッパーの一つである。そのためO/Rマッパーについての簡単な説明を行う。
　O/Rマッパーとは、データベースへのアクセスを行う際に、JDBCを直接利用した場合に起きてしまう問題を解消するために使うものである。そのためO/Rマッパーを利用したアプリケーションの開発を行うことで、簡単にデータベースとの連携ができる。

## eclipseでのICIQLの導入方法

### ダウンロードから配置まで
1.[iciql-1.6.5.jar](https://github.com/gitblit/iciql-maven/raw/master/com/iciql/iciql/1.6.5/iciql-1.6.5.jar)をダウンロードする。
2.プロジェクト内にあるWebContent/WEB-INF/libにダウンロードしたiciql-1.6.5.jarを配置する。
上記の2つだけでとりあえずICIQLが使えるようになります。

### モデルクラス生成
　モデルクラスとは、データベースにアクセスするときに利用するクラス。データを一括で管理出来るようになる。(Beanのようなもの)
　モデルクラスを生成したいデータベースがすでにあるものとして進めます。
　以下手順
1.eclipse上で生成されたモデルクラスを入れるパッケージを作成する。
2.cmdを起動する。
3.以下のコマンドを実行する。
```
java -Xbootclasspath/a:[JDBCドライバの絶対パス] -jar [iciql-1.6.5.jarの絶対パス] -url jdbc:mysql://localhost:3306/[データベース名] -user  [postgresユーザー名] -password [postgresユーザーのパスワード] -package [eclipseで作成したパッケージ名] -folder [今回作成するモデルクラスを出力するディレクトリの絶対パス]
```
4.[今回作成するモデルクラスを出力するディレクトリの絶対パス]で指定したフォルダにモデルクラスが生成されているので、それをeclipseで作成したパッケージに入れる。


## SQL文の実行

モデルクラスを入れたパッケージをimportして利用する。

### SELECT文

``` servlet.java
/** 接続するDBの設定(userNameとpasswordはpostgresログイン時に利用しているものを書く **/
Db db= Db.open(jdbcUrl, userName, password);
/** 操作するテーブルに対応するインスタンス生成。今回はHelloテーブル **/
Hello h = new Hello();
/** SELECT文の戻り値は複数になるのでHello型のListを生成 **/
List<Hello> hellos= db
    .from(h)//Helloテーブルの
    .where(h.user)//"user"が
    .oneOf("tanaka", "suzuki")//"tanaka"か"suzuki"と一致している
    .and(h.comment)//かつ、"comment"が
    .like("%hello%")//曖昧検索で"hello"と一致している
    .and(h.userId)//かつ、"userId"が
    .lessThan(10)//10以下である物を
    .orderByDesc(h.timestamp)//"timestamp"を降順で
    .select();//SELECT文を実行する
db.close();
```

### INSERT文

まずモデルクラスにINSERTしたい情報を引数に持つコンストラクタを生成する。

``` Hello.java
    /** 自動生成された物 **/
    @IQColumn(primaryKey=true, autoIncrement=true, nullable=false)
    public Integer userId;

    @IQColumn(nullable=false)
    public String user;

    @IQColumn(nullable=false)
    public String comment;

    @IQColumn(nullable=false)
    public TimeStamp timestamp;

    /** コンストラクタ作成 **/
    public Hello(int userid, String user, String comment, TimeStamp timestamp){
        this.userid = userid;
        this.user = user;
        this.comment = comment;
        this.timestamp = timestamp;
    }
```

次にINSERT文を実行するためのコード

``` servlet.java
/** 接続するDBの設定(userNameとpasswordはpostgresログイン時に利用しているものを書く **/
Db db= Db.open(jdbcUrl, userName, password);
/** 操作するテーブルに対応するインスタンス生成。今回はHelloテーブル **/
Hello h = new Hello();
/** INSERT文の戻り値はINTなのでint型の変数を生成,変数を生成せずに実行も可 **/
int i  = db
    .insert(new Hello(2, "takahasi", "hello", "2016-08-03 12:00:23");
db.close();
```

### UPDATE文

``` servlet.java
/** 接続するDBの設定(userNameとpasswordはpostgresログイン時に利用しているものを書く **/
Db db= Db.open(jdbcUrl, userName, password);
/** 操作するテーブルに対応するインスタンス生成。今回はHelloテーブル **/
Hello h = new Hello();
/** UPDATE文の戻り値はINTなのでint型の変数を生成,変数を生成せずに実行も可 **/
int i  = db
    .from(h)//Helloテーブルの
    .set(h.user)//userを
    .to("satou")//"satou"にします
    .increment(h.userId)//useridを
    .by(20)//20増加させます
    .where(h.user)//"user"が
    .is("tanaka")//"tanaka"と一致しているものを
    .update();//UPDATE文を実行する
db.close();
```

### DELETE文

``` servlet.java
/** 接続するDBの設定(userNameとpasswordはpostgresログイン時に利用しているものを書く **/
Db db= Db.open(jdbcUrl, userName, password);
/** 操作するテーブルに対応するインスタンス生成。今回はHelloテーブル **/
Hello h = new Hello();
/** DELETE文の戻り値はINTなのでint型の変数を生成,変数を生成せずに実行も可 **/
int i  = db
    .from(h)//Helloテーブルの
    .where(h.user)//"user"が
    .is("satou")//"satou"と一致しているものを
    .delete();//DELETE文を実行する
db.close();
```

### joinのやり方
自動生成したモデルクラスのみではjoinができない。AテーブルとBテーブルをjoinしたいのであれば、モデルクラスAとモデルクラスBの両方の要素をもったモデルクラスABを作成しなければならない。また作成したモデルクラスABが持っている要素全てを引数に持つコンストラクタを作成しなければならない。

``` servlet.java
/** 接続するDBの設定(userNameとpasswordはpostgresログイン時に利用しているものを書く **/
Db db = Db.open(jdbcUrl, userName, password);
/** 結合するテーブルのインスタンス生成を行う。今回はHelloテーブルとUserInfoテーブルを結合する **/
Hello h = new Hello();
User u = new User();
/** HelloUserというモデルクラスを今回は作成しておかなくては行けない **/
List<HelloUser> helloInfos = db
    .from(h)//Helloテーブルに
    .leftJoin(u)//userテーブルをleftjoinします
    .on(u.userid)//joinにuserテーブルのuseridを利用します
    .is(h.userid)//つなげるのはhelloテーブルのuseridです
    .select(new HelloUser(){{//selectで取得したものをHelloUser型にします。その際の中身は{{}}内で入れています。
        userid = h.userid;
        user = h.user;
        comment = h.comment;
        timestamp = h.timestamp;
        tel = u.tel;
        address = u.address;
    }})
```



### テーブルの一部分の情報だけを取得したい時

例えばUserテーブル内でのuserが'tanaka'のuseridを取得したい場合

``` servlet.java
/** 接続するDBの設定(userNameとpasswordはpostgresログイン時に利用しているものを書く **/
Db db = Db.open(jdbcUrl, userName, password);

User u = new User();

u = db.from(u).where(u.user).is("tanaka").selectFrist();//userテーブルの中でuserが'tanaka'のデータを取得
int userid = u.userid;//u.useridでuに入ったデータの中のuseridを取得