5年の開発期間を経てリリースされたHyperSQL 2.0

2010年6月、Pure JavaデータベースHSQLDBの最新版となるHyperSQL 2.0がリリースされた。前バージョンとなるHSQLDB 1.8のリリースから実に5年の開発期間を経てリリースされたことになる。コードは大幅な書き換えが行われ、コア部分は完全にマルチスレッドで動作するようになった。

また、2フェーズロック、MVCC(多重バージョン並行処理制御)をサポートし、トランザクション制御レベルとして従来サポートされていたSERIALIZABLEとREAD COMMITTEDに加えてREPEATABLE READとREAD UNCOMMITTEDが新たに追加されている。

まずは動かしてみよう

それでは実際にHyperSQLを動かしてみよう。

ダウンロードしたディストリビューションのhsqldb/binディレクトリに格納されているrunManager.batをダブルクリックしてみよう。以下のような管理ツールが起動するはずだ(runManagerSwing.batでSwingベースの管理ツールを利用することもできる)。

図1 管理ツール(接続ダイアログ)

図2 管理ツール(接続後)

HyperSQLにはいくつかの起動モードがあるが、デフォルトではURLに「jdbc:hsqldb:mem:.」と表示されているが、このまま接続するとインメモリモード(メモリ上にしかデータを持たないためプロセスを終了するとデータも消えてしまう)で使用できる。

まずは管理ツール上からCREATE文や任意のSQLを発行して動作を確認してみてほしい。

Javaプログラムからの利用方法

HyperSQLには以下のようなモードがある。一時的なデータの格納であればインメモリモード、スタンドアロンアプリケーションに組み込むのであればスタンドアロンモード、Webアプリケーションであればサーバモードなど、用途に応じて使い分けよう。

HyperSQLの起動モード

モード 接続URL 説明
インメモリ jdbc:hsqldb:mem:. データをメモリ上にのみ保持する。プロセスを終了するとデータも消えてしまう
スタンドアロン jdbc:hsqldb:file:<path> ファイルを直接読み書きするモード。組み込み用途などサーバを起動する必要がない場合に使用する
サーバ jdbc:hsqldb:hsql://<hostname>/ 通常のRDBMSのようにサーバプロセスとして実行。通常のデータベースサーバと同様の用途で使用する
Webサーバ jdbc:hsqldb:http://<hostname>/? HTTPで通信を行うサーバプロセスとして実行。ファイアウォールを越える必要がある場合などに使用する
サーブレット jdbc:hsqldb:http://<hostname>/? Webサーバモードと同様だが、サーバプロセスを起動する代わりにサーブレットエンジンを利用できる

hsqldb/binディレクトリに格納されているrunServer.batでサーバモード、runWebServer.batでWebサーバモードで起動することが可能だ。インメモリモードとスタンドアロンモードはサーバを起動する必要はない。

また、以下のようにコマンドラインからサーバの起動クラスを直接指定して起動することも可能だ。

// サーバモードで起動
java -cp ../lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:mydb --dbname.0 xdb

// Webサーバモードで起動
java -cp ../lib/hsqldb.jar org.hsqldb.server.WebServer --database.0 file:mydb --dbname.0 xdb

HyperSQLに接続するJavaプログラムは以下のようになる(例外処理などは省いているので注意してほしい)。実行時にはJDBCドライバとしてhsqldb.jarをクラスパスに追加しておく必要がある。また、接続URLはHyperSQLのモードに応じて変更してほしい。

Connection conn = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/", "SA", "");
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM USER_INFO");
ResultSet rs = stmt.executeQuery();

while(rs.next()){
  Integer userId = rs.getInt("USER_ID");
  String firstName = rs.getString("FIRST_NAME");
  String lastName = rs.getString("LAST_NAME");

  System.out.println(String.format("%d: %s %s", userId, firstName, lastName));
}

rs.close();
stmt.close();
conn.close();