HSQLDB使い方メモ

HSQLDB の使い方メモ。

#環境
##OS
Windows7 64bit

##Java
1.7.0_25

##HSQLDB
2.3.0

#ダウンロード
[ここ](http://sourceforge.net/projects/hsqldb/files/hsqldb/) から欲しいバージョンの zip をダウンロード。

zip を展開してできる `hsqldb-x.x.x/hsqldb` フォルダのパスを `%HSQLDB_HOME%` とする。

Gradle を使っている場合は以下の依存関係を設定。

```groovy:
compile 'org.hsqldb:hsqldb:2.3.2'
```

https://search.maven.org/search?q=g:org.hsqldb%20AND%20a:hsqldb

#サーバモードで起動して DatabaseManager で接続する
コマンドプロンプトを開き、サーバーモードで HSQLDB を起動する。

```batch:
>cd /d %HSQLDB_HOME%\lib

>java -cp hsqldb.jar org.hsqldb.Server -database db/test
```

HSQLDB が起動して、 `%HSQLDB_HOME%\lib\db\test` にデータベースのファイル類が生成される。

##DatabaseManager で接続する
コマンドプロンプトから DatabaseManager を起動する。

```batch:
>cd /d %HSQLDB_HOME%\lib

>java -cp hsqldb.jar org.hsqldb.util.DatabaseManager
```

※v2.6.0 以降は `org.hsqldb.util.DatabaseManagerSwing` を使用する。

http://hsqldb.org/doc/2.0/changelist_2_0.txt
> The DatabaseManager class is no longer included in the Jars. Use DatabaseManagerSwing instead. 

「Type」で `HSQL Database Engine Server` を選択して、「Ok」を選択。

![DatabaseManagerのConnect.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/5209b42d-55b2-56da-4505-0af861443f8e.jpeg)

##テーブルを作成する
次の SQL を実行する。

```sql:TEST_TABLE作成DDL
CREATE TABLE TEST_TABLE (
  ID    INTEGER NOT NULL IDENTITY,
  VALUE VARCHAR(256)
)
```

![テーブルの作成.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/19f3a4b7-39fd-ad4b-1383-b679570ad8a0.jpeg)

「View」の「Refresh Tree」を選択したら、左のツリーに作成した `TEST_TABLE` が表示される。

![TEST_TABLEが追加されている様子.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/f6a9b835-6145-a4db-2053-af02bd2152b4.jpeg)

##データの挿入
```sql:テストデータ
INSERT INTO TEST_TABLE (VALUE) VALUES ('HOGE');
INSERT INTO TEST_TABLE (VALUE) VALUES ('FUGA');
INSERT INTO TEST_TABLE (VALUE) VALUES ('PIYO');
```

![テストデータの挿入結果確認.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/d388cff7-be07-0722-0b7f-8175da6d101c.jpeg)

#プログラムから DB に接続する
上で作った test データベースにプログラムから接続する。

##jar の追加
`%HSQLDB_HOME%\lib\hsqldb.jar` をクラスパスに追加する。

##実装
JDBC ドライバは「`org.hsqldb.jdbcDriver`」、URL は「`jdbc:hsqldb:file:<DBフォルダのパス>/<DB名>`」を指定。

```java:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class Main {
    public static void main(String[] args) throws Exception {
        String dbDir = "%HSQLDB_HOME%/lib/db/test";
        
        Class.forName("org.hsqldb.jdbcDriver");
        String url = "jdbc:hsqldb:file:" + dbDir;
        String user = "sa";
        String password = "";
        
        Connection con = DriverManager.getConnection(url, user, password);
        Statement stat = con.createStatement();
        
        stat.execute("SELECT * FROM TEST_TABLE");
        ResultSet rs = stat.getResultSet();
        
        while (rs.next()) {
            int id = rs.getInt("ID");
            String value = rs.getString("VALUE");
            
            System.out.println(String.format("ID=%d, VALUE=%s", id, value));
        }
        
        rs.close();
        stat.close();
        con.close();
    }
}
```

```text:実行結果
ID=0, VALUE=HOGE
ID=1, VALUE=FUGA
ID=2, VALUE=PIYO
```

#インメモリモードで使用する
データをメモリ上に保存する方法。

当然 JVM が終了したらデータは消えるが、サンプルアプリとかで動作確認が目的で、別に永続化が必要ないときとかは便利だと思う。

```java:
package sample.hsqldb;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class InMemorySample {
    
    public static void main(String[] args) throws Exception {
        // JDBC ドライバロード
        Class.forName("org.hsqldb.jdbcDriver");
        
        // データベースに接続
        Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:test", "sa", "");
        
        // テーブル作成
        Statement st = connection.createStatement();
        st.executeUpdate("CREATE TABLE TEST_TABLE (ID INTEGER, VALUE VARCHAR(10))");
        
        // データ挿入
        st.executeUpdate("INSERT INTO TEST_TABLE VALUES (1, 'HOGE')");
        st.executeUpdate("INSERT INTO TEST_TABLE VALUES (2, 'FUGA')");
        
        // データ取得
        ResultSet rs = st.executeQuery("SELECT * FROM TEST_TABLE");
        
        while (rs.next()) {
            System.out.println("ID=" + rs.getInt("ID") + ", VALUE=" + rs.getString("VALUE"));
        }
        
        st.close();
        connection.close();
    }
}
```

#スタンドアロンモードで利用する

サーバは立ち上げず、組み込みで DB を起動する。
データはファイルに保存させる。

```java:
package sample.hsqldb;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class Main {
    public static void main(String[] args) throws Exception {
        // JDBC ドライバロード
        Class.forName("org.hsqldb.jdbcDriver");
        
        // データベースに接続
        Connection connection = DriverManager.getConnection("jdbc:hsqldb:file:testdb/testdb;shutdown=true", "SA", "");
        
        // テーブル作成
        Statement st = connection.createStatement();
        st.executeUpdate("CREATE TABLE TEST_TABLE (ID INTEGER, VALUE VARCHAR(10))");
        
        // データ挿入
        st.executeUpdate("INSERT INTO TEST_TABLE VALUES (1, 'HOGE')");
        st.executeUpdate("INSERT INTO TEST_TABLE VALUES (2, 'FUGA')");
        
        // データ取得
        ResultSet rs = st.executeQuery("SELECT * FROM TEST_TABLE");
        
        while (rs.next()) {
            System.out.println("ID=" + rs.getInt("ID") + ", VALUE=" + rs.getString("VALUE"));
        }
        
        st.close();
        connection.close();
    }
}
```

URL を `jdbc:hsqldb:file:<ローカルのパス>` にすれば、スタンドアロンモードで利用できる。

__参考__

- [HSQLDB Memory-Onlyモード: 開発生活のメモ](http://pontus.cocolog-nifty.com/blog/2007/11/hsqldb_memoryon_dcb5.html)


#参考
- [HSQLDBの使い方 - 安藤友晴のページ/ソフトウェア特論 (2003年度)/稚内北星学園大学](http://www.wakhok.ac.jp/~tomoharu/tokuron2003/hsqldb/)
- [HSQLDBのセットアップ - らどくらのはくつーる](http://www50.tok2.com/home/oppama/hsqldb-start.html)