110

(我已经在内存中看到了 H2 数据库 - Init schema via Spring/Hibernate question;它在这里不适用。)

我想知道 H2 中是否有一个设置可以让我在连接到它时自动创建一个模式。如果有帮助,我只对内存中的情况感兴趣。

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

4

6 回答 6

199

是的,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'";

请注意,双反斜杠 ( \\) 仅在 Java 中是必需的。;之前的反斜杠INIT是必需的。

于 2011-03-08T05:05:27.167 回答
26

如果您将 spring 与 一起使用application.yml,则以下内容将为您工作:

spring:
  datasource:
    url: jdbc:h2:mem:mydb;DB_CLOSE_ON_EXIT=FALSE;MODE=PostgreSQL;INIT=CREATE SCHEMA IF NOT EXISTS calendar
于 2017-12-29T09:28:11.093 回答
9

Thomas 写的是正确的,除此之外,如果您想初始化多个模式,您可以使用以下内容。请注意,两个 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();

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

于 2018-04-06T14:33:38.567 回答
8

“默认情况下,当应用程序调用DriverManager.getConnection(url, ...)并且 URL 中指定的数据库尚不存在时,会创建一个新的(空)数据库。”—<a href="http://www.h2database.com/html/features. html#database_only_if_exists" rel="noreferrer">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);
        }
    }
}
于 2011-03-07T23:02:55.060 回答
3

如果您正在使用 Spring Frameworkapplication.yml并且无法使测试在INIT属性上找到 SQL 文件,则可以使用该classpath:符号。

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

url=jdbc:h2:~/test;INIT=RUNSCRIPT FROM 'classpath:init.sql';DB_CLOSE_DELAY=-1;
于 2019-12-09T20:07:37.867 回答
0

如果您使用的是 spring 和 xml 配置,下面是一个示例:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close" depends-on="h2Server">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url"
          value="jdbc:h2:mem:testdb;INIT=RUNSCRIPT FROM 'classpath:db/create_tables.sql'\;RUNSCRIPT FROM 'classpath:db/insert.sql';TRACE_LEVEL_FILE=4;TRACE_LEVEL_SYSTEM_OUT=3;"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
于 2021-06-28T10:10:24.843 回答