我可以让H2在内存数据库中自动创建一个模式吗?

Lai*_*son 83 java sql database h2

(我已经在内存中看到了H2数据库 - 通过Spring/Hibernate问题的Init模式 ;它在这里不适用.)

我想知道H2中是否有设置允许我在连接时自动创建模式.如果它有帮助,我只对内存中的情况感兴趣.

H2在URL的末尾支持各种以分号分隔的修饰符,但我找不到用于自动创建模式的修饰符.有这样的功能吗?

Tho*_*ler 153

是的,H2支持在连接时执行SQL语句.您可以运行脚本,也可以只运行一两个语句:

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'";
Run Code Online (Sandbox Code Playgroud)

请注意,\\只有Java中才需要双反斜杠().前的反斜杠(ES);INIT是必需的.

  • 请注意,如果您将H2与hibernate一起使用并希望通过调用**RUNSCRIPT**来运行多个脚本,则应键入三个反斜杠(\\\\).例如,你应该设置`<property name ="hibernate.connection.url"> jdbc:h2:mem:test; INIT = RUNSCRIPT FROM'script1.sql'\\\; RUNSCRIPT FROM script2.sql'</ property >`在你的hibernate配置中. (2认同)
  • @pinkpanther 是的,请参阅 http://stackoverflow.com/questions/4490138/problem-with-init-runscript-and-relative-paths (2认同)

tra*_*god 8

"默认情况下,当应用程序调用DriverManager.getConnection(url, ...)并且URL中指定的数据库尚不存在时,将创建一个新的(空)数据库." - H2数据库.

附录:@Thomas Mueller展示了如何在Connection执行SQL,但我有时只是在代码中创建并填充,如下所示.

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Zeu*_*eus 8

托马斯写的是正确的,除此之外,如果你想初始化多个模式,你可以使用以下内容.请注意\\;,两个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();
Run Code Online (Sandbox Code Playgroud)

参考:http://www.h2database.com/html/features.html#execute_sql_on_connection


Mar*_*unt 7

如果您使用带有application.yml的spring,则以下内容适用于您

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

  • 如果您还想设置架构:`INIT=CREATE SCHEMA IF NOT EXISTS calendar\;SET SCHEMA calendar` (2认同)

Dhe*_*rik 7

如果您正在使用 Spring Framework,并且在application.yml测试中无法找到INIT属性上的 SQL 文件,则可以使用该classpath:表示法。

例如,如果您init.sql在 上有一个 SQL 文件src/test/resources则只需使用

url=jdbc:h2:~/test;INIT=RUNSCRIPT FROM 'classpath:init.sql';DB_CLOSE_DELAY=-1;
Run Code Online (Sandbox Code Playgroud)