WindowsでApache Derbyを構築する手順書

JDKだけではなく、Glassfish、WebSphere、Apache Hiveなど、
Java関連のツールによくバンドルされている印象を持つApache Derby。

軽量・組み込み/サーバー・Pure Javaなので、あらゆる用途で利用でき、
学習用としても利用しやすいデータベースです。

そんな、Derbyの構築手順（インストール～データ作成まで）をまとめて、
もっと手軽に利用できるDBとして扱えるようになろうという想いから書きました。

# Derbyのインストール
バンドルされているDerbyを使う場合は、インストールは不要です。
バンドルしているツールをインストールしていない場合、
または、別途インストールしたい場合は、下記のページからダウンロードしてください。

http://db.apache.org/derby/derby_downloads.html

この記事を書いている時点の最新版は[10.13.1.1](http://db.apache.org/derby/releases/release-10.13.1.1.cgi)でした。
そのバージョンのリンクをクリックし、zipをダウンロードします。
[db-derby-10.13.1.1-bin.zip](http://www-eu.apache.org/dist//db/derby/db-derby-10.13.1.1/db-derby-10.13.1.1-bin.zip)

上記のファイルを解凍します。
保存先は任意です。当マニュアルでは以下のディレクトリに移動させました。
C:\Tools\derby
※パス名短くしたかったので「db-derby-10.13.1.1-bin」を「derby」にリネームしてます。

# Derbyの基本的な設定

システム環境変数にDerbyに関する設定を追加します。
DERBY_HOME=C:\Tools\derby
PATH=（中略）;%DERBY_HOME%\bin

次に、先ほどPATHに指定したbinフォルダをコマンドプロンプトで起動。

```bat
:: derby.propertiesを作成し、ユーザー/パスワードを設定する。
C:\Tools\derby\bin>type nul > derby.properties
C:\Tools\derby\bin>notepad derby.properties
```

メモ帳に以下の内容をコピペ。
終われば、保存して閉じる。

```properties:derby.properties
derby.authentication.provider=BUILTIN
derby.connection.requireAuthentication=true
derby.database.sqlAuthorization=true
derby.database.fullAccessUsers=admin
derby.database.readOnlyAccessUsers=guest
derby.user.admin=admin
derby.user.guest=guest
```

※上記の設定をするとテーブルやデータの書き込みをする場合、adminで接続する必要があります。
それが面倒な場合は、`derby.connection.requireAuthentication`をfalseにしてください。
別にderby.propertiesを作成しなくても、DB作成できるのですが、
後々、ユーザーを設定したいとか起きたときにあらかじめ作成しておいた方が便利だと思ったので書きました。

```bat
:: DBを保存する用のディレクトリを作成
C:\Tools\derby\bin>md %DERBY_HOME%\dat
```

# データベースの作成
基本設定ができたので、データベースの作成に入ります。

なお、Derbyのijコマンドについてはここでは割愛します。
詳細はこちらで → [JavaDBメモ](http://www.ne.jp/asahi/hishidama/home/tech/java/javadb.html)
また、ijのhelpコマンドでも確認できますので、気になりましたらそちらで。
ただ、ijコマンドは文末に；（セミコロン）が絶対にいるので、そこだけ初めから注意しておいてください。
；を忘れていても、次の行で；してEnterすればコマンド実行できますので焦らずに。

今回はデータベース、テーブル、データの作成のコマンドをsqlファイルに書いておいて、
ijコマンドでそのsqlファイルを実行していくスタイルを取ります。

```sql:database-create.sql
connect 'jdbc:derby:c:/Tools/derby/dat/test;user=admin;password=admin;create=true';
```

※derby.propertiesでderby.connection.requireAuthenticationをfalseにした場合は、
　user=admin;password=admin;の部分は不要です。（以下、同様）

```bat
:: database-create.sqlが保存されているディレクトリに移動
C:\Tools\derby\bin>cd D:\workspace\script
:: データベースの作成。
D:\workspace\script>ij.bat database-create.sql
```

# テーブルの作成
続きまして、テーブルを作成します。
DerbyではTABLEがもし存在すれば、DROPを実行といった文がないので、そこは人が判断する必要があります。
もっとも、そういう関数を作れば解決するのですが、今回はその対応はしません。

```sql:users-create.sql
connect 'jdbc:derby:c:/Tools/derby/dat/test;user=admin;password=admin';

MAXIMUMDISPLAYWIDTH 15;

--DROP TABLE users if needed

show tables in admin;

CREATE TABLE users (
    id INT NOT NULL PRIMARY KEY
        GENERATED ALWAYS AS IDENTITY
        (START WITH 1, INCREMENT BY 1),
    login_id VARCHAR(20) NOT NULL,
    password VARCHAR(20) NOT NULL,
    user_name VARCHAR(20) NOT NULL,
    birthday CHAR(8),
    email VARCHAR(40) NOT NULL,
    address VARCHAR(200),
    credit_card_number CHAR(16),
    authority_type CHAR(1) NOT NULL,
    is_deleted CHAR(1) NOT NULL,
    created_at TIMESTAMP NOT NULL,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_by VARCHAR(20) NOT NULL
);

CREATE UNIQUE INDEX ui_users_01 ON users (
    login_id
);
CREATE UNIQUE INDEX ui_users_02 ON users (
    email
);
CREATE UNIQUE INDEX ui_users_03 ON users (
    credit_card_number
);

show tables in admin;
describe users;

commit;
```

```bat
:: usersテーブルの作成
D:\workspace\script>ij.bat users-create.sql
```

# レコードの挿入
最後にレコードを挿入します。

```sql:users-insert.sql
connect 'jdbc:derby:c:/Tools/derby/dat/test;user=admin;password=admin';

MAXIMUMDISPLAYWIDTH 15;

select * from users;

INSERT INTO users VALUES 
(DEFAULT, 'sj', 'berkay', 'sercan', '20000318', 'sercan@gmail.com',
'19 Mc Cabe Street', '1234567890123456', '1', '0', current_timestamp, current_timestamp, 'admin');
INSERT INTO users VALUES 
(DEFAULT, 'br', 'ugur', 'oljay', '19980322', 'oljay@gmail.com',
'19 Mc Cabe Street 2145', '1234567890123450', '1', '0', current_timestamp, current_timestamp, 'admin');

select * from users;

commit;
```

```bat
:: usersテーブルにデータを挿入。
D:\workspace\script>ij.bat users-insert.sql
```

DerbyのSQLは見ての通りほぼ標準通りのSQLで書けます。
DMLで違うのはLIMIT句がない（ROW_NUMBER関数かOFFSET・FETCH句で代用）ことと、
"CASE 条件式 WHEN"のみをサポート。（"CASE WHEN ~"は使用できない）くらいです。
関数はマニュアルを参照してください。COALESCEとかREPLACEがなかったりします。

# 参考
[JavaDBメモ](http://www.ne.jp/asahi/hishidama/home/tech/java/javadb.html)
[developerWorks - Apache Derby を使用した開発](http://www.ibm.com/developerworks/jp/views/opensource/libraryview.jsp?search_by=Apache+Derby+%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E9%96%8B%E7%99%BA)
[Derby Reference Manual](https://builds.apache.org/job/Derby-docs/lastSuccessfulBuild/artifact/trunk/out/ref/index.html)