インメモリデータベースにH2スキーマを自動作成させることはできますか?


93

(私はすでに見ました メモリ内 H2データベースを -Spring / Hibernate質問によるInitスキーマ。ここでは適用されません。)

H2に接続時にスキーマを自動作成できる設定があるかどうか知りたいのですが。それが役立つ場合、私はメモリ内の場合にのみ興味があります。

H2は、URLの末尾でセミコロンで区切られたさまざまな修飾子をサポートしていますが、スキーマを自動的に作成する修飾子は見つかりませんでした。そのような機能はありますか?

回答:


171

はい、H2は接続時のSQLステートメントの実行をサポートしています。スクリプトを実行するか、ステートメントを1つまたは2つ実行します。

String url = "jdbc:h2:mem:test;" + 
             "INIT=CREATE SCHEMA IF NOT EXISTS TEST"
String url = "jdbc:h2:mem:test;" + 
             "INIT=CREATE SCHEMA IF NOT EXISTS TEST\\;" + 
                  "SET SCHEMA TEST";
String url = "jdbc:h2:mem;" + 
             "INIT=RUNSCRIPT FROM '~/create.sql'\\;" + 
                  "RUNSCRIPT FROM '~/populate.sql'";

二重のバックスラッシュ(\\)はJava内でのみ必要であることに注意してください。;内の前のバックスラッシュINITは必須です。


どうもありがとうございました; (優秀な)ドキュメントでそれをどのように逃したかわかりません。
Laird Nelson

ありがとう、生成されたxmlのスキーマ名を使用するliquibaseから生成されたチェンジセットを使用していたので、うまくいきました。
Jaime Hablutzel、2011

2
H2をhibernateで使用していて、RUNSCRIPTを呼び出して複数のスクリプトを実行する場合は、3つのバックスラッシュ(\\\)を入力する必要があります。たとえば<property name="hibernate.connection.url">jdbc:h2:mem:test;INIT=RUNSCRIPT FROM 'script1.sql'\\\;RUNSCRIPT FROM script2.sql'</property>、休止状態の構成で設定する必要があります。
ジョニー

@ジョニーよろしいですか?;はエスケープ;する必要がないようです(の前にエスケープされていないものがありますINIT)。バックスラッシュを1つだけ使用するとうまくいきますか?'script1.sql'\;RUNSCRIPT...
Thomas Mueller

1
@pinkpantherはい、stackoverflow.com
Thomas Mueller

14

application.ymlでSpringを使用している場合、以下が機能します

spring: datasource: url: jdbc:h2:mem:mydb;DB_CLOSE_ON_EXIT=FALSE;MODE=PostgreSQL;INIT=CREATE SCHEMA IF NOT EXISTS calendar


この方法でGrails 3でスキーマを作成することもできます
xtheshadowgod

1
どうもありがとうございました。このヒントを使用して、コードが4日間機能しない問題を修正しました。
ディープボーイ2018

9

Thomasが書いたものは正しいですが、それに加えて、複数のスキーマを初期化したい場合は、以下を使用できます。\\;2つのcreateステートメントが分離されていることに注意してください。

    EmbeddedDatabase db = new EmbeddedDatabaseBuilder()
                    .setType(EmbeddedDatabaseType.H2)
                    .setName("testDb;DB_CLOSE_ON_EXIT=FALSE;MODE=Oracle;INIT=create " +
                            "schema if not exists " +
                            "schema_a\\;create schema if not exists schema_b;" +
                            "DB_CLOSE_DELAY=-1;")
                    .addScript("sql/provPlan/createTable.sql")
                    .addScript("sql/provPlan/insertData.sql")
                    .addScript("sql/provPlan/insertSpecRel.sql")
                    .build();

ref:http : //www.h2database.com/html/features.html#execute_sql_on_connection


8

「デフォルトでは、アプリケーションが呼び出さDriverManager.getConnection(url, ...)れ、URLで指定されたデータベースがまだ存在しない場合、新しい(空の)データベースが作成されます。」— H2データベース

補遺:@Thomas Mueller がConnectionSQL実行する方法を示していますが、以下に提案するように、コードを作成してデータを入力するだけの場合もあります。

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

/** @see http://stackoverflow.com/questions/5225700 */
public class H2MemTest {

    public static void main(String[] args) throws Exception {
        Connection conn = DriverManager.getConnection("jdbc:h2:mem:", "sa", "");
        Statement st = conn.createStatement();
        st.execute("create table customer(id integer, name varchar(10))");
        st.execute("insert into customer values (1, 'Thomas')");
        Statement stmt = conn.createStatement();
        ResultSet rset = stmt.executeQuery("select name from customer");
        while (rset.next()) {
            String name = rset.getString(1);
            System.out.println(name);
        }
    }
}

はい、それはカタログまたはデータベースであり、その中のスキーマではありません。したがって、たとえばjdbc:h2:mem:testへの接続を開くことができますが、デフォルトではPUBLICスキーマに配置され、他のスキーマは存在しません。
Laird Nelson、

0

Spring Frameworkを使用application.ymlしていて、テストでINITプロパティのSQLファイルを見つけるのに問題がある場合は、classpath:表記法。

たとえば、init.sqlSQLファイルがにある場合はsrc/test/resources、次のように使用します

url=jdbc:h2:~/test;INIT=RUNSCRIPT FROM 'classpath:init.sql';DB_CLOSE_DELAY=-1;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.