【H2 Database】Webアプリケーション起動時にデータベースを起動する方法の紹介

Webアプリケーションを開発するときにデータベースを使用するため、ローカル開発環境で起動することがあると思います。

一度でも起動しておけば問題ありませんが、ローカル開発環境の再起動などを実施した場合は、ときどき起動することを忘れてしまうと実行時にデータベース接続のエラーが発生することがあります。

Webアプリケーション起動時にデータベースも併せて起動してくれると助かると思うことがありませんか。H2 Databaseでは、Webアプリケーション起動時にデータベースも起動することができます。

今回は、H2 Databaseを使用してWebアプリケーション起動時にデータベースを起動する方法を紹介します。

スポンサーリンク

環境

検証に使用した環境/ライブラリを以下に記載します。

  • Java
    • バージョン:11
  • H2 Database
    • バージョン:1.4.200(2019-10-14)

起動方法

Webアプリケーション起動時にデータベースも併せて起動するためには、web.xmlに次の情報を指定します。

<listener>
    <listener-class>org.h2.server.web.DbStarter</listener-class>
</listener>

起動時の初期化処理(ServletContextListener.contextInitialized)にて、データベースへアクセスするための処理が行われます。

ただし、このままでは次の情報でデータベースへアクセスすることになります。

  • URL:jdbc:h2:~/test
  • User:sa
  • Password:sa

接続先などの情報を変更するためには、web.xmlに次のような情報を指定します。

<context-param>
    <param-name>db.url</param-name>
    <param-value>jdbc:h2:~/test</param-value>
</context-param>
<context-param>
    <param-name>db.user</param-name>
    <param-value>sa</param-value>
</context-param>
<context-param>
    <param-name>db.password</param-name>
    <param-value>sa</param-value>
</context-param>
<context-param>
    <param-name>db.tcpServer</param-name>
    <param-value>-tcpAllowOthers</param-value>
</context-param>

指定した値は、それぞれ以下に記載する情報になります。

  • db.url
    • 接続先のURLを指定してください。
  • db.user
    • 接続先のユーザ名を指定してください。
  • db.password
    • 接続先のパスワードを指定してください。
  • db.tcpServer
    • サーバモードで起動するために指定してください。

【注意】
サーバモードで起動する場合は、必ずdb.tcpServerを指定するようにしてください。指定しないとサーバモードでは起動しません。

最終的なweb.xmlは、次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
  <context-param>
    <param-name>db.url</param-name>
    <param-value>jdbc:h2:tcp://localhost/~/test</param-value>
  </context-param>
  <context-param>
    <param-name>db.user</param-name>
    <param-value>sa</param-value>
  </context-param>
  <context-param>
    <param-name>db.password</param-name>
    <param-value></param-value>
  </context-param>
  <context-param>
    <param-name>db.tcpServer</param-name>
    <param-value>-tcpAllowOthers</param-value>
  </context-param>
  <listener>
    <listener-class>org.h2.server.web.DbStarter</listener-class>
  </listener>
</web-app>

接続方法

H2 Databaseで起動したデータベースへ接続するためのコネクションを取得する方法として、以下の方法があります。

  1. DriverManager.getConnectionからコネクションを取得する。
  2. Servletコンテキストからコネクションを取得する。

DriverManager.getConnectionからコネクションを取得する

DriverManager.getConnectionを使用してコネクションを取得する方法は、シンプルなデータベース接続をするために行われている方法で、次のように使用にします。

try (Connection connection = DriverManager.getConnection(url, user, passwod)) {
} catch (SQLException exception) {
  exception.printStackTrace();
}

Servletコンテキストからコネクションを取得する

H2 Databaseでデータベースを起動した場合は、初期化処理時にServletコンテキストにコネクションが設定されます。取得して使用する場合は、次のように使用します。

Connection connection = (Connection)ServletContext.getServletContext().getAttribute("connection");

【注意点】
Servletコンテキストから取得したコネクションの終了処理は実行しないでください。初期化処理時にコネクションを保持しているため、一度コネクションを閉じてしまうと再取得ができなくなります。このため、最初はアクセスできても、2回目以降にアクセスすると次のような例外が発生します。

org.h2.jdbc.JdbcSQLNonTransientException: オブジェクトはすでに閉じられています

終了方法

終了処理については、特に何もする必要がありません。サーバモードで起動している場合でも自動的に停止します。

参考

org.h2.server.web.DbStarterの処理内容を確認したい場合は、以下の方法で確認することができます。

公式サイト

公式サイトからダウンロードしたファイルにはソースファイルも含まれています。対象ファイルは次の場所にあります。

h2\src\main\org\h2\server\web\DbStarter.java

GitHub

Githubで確認することもできます。

h2database/h2/src/main/org/h2/server/web/DbStarter.java at master · h2database/h2database
H2 is an embeddable RDBMS written in Java. Contribute to h2database/h2database development by creating an account on Git...