메모리 내 데이터베이스에서 H2가 스키마를 자동 생성하도록 할 수 있습니까?


95

(이미 H2 데이터베이스 In memory-Init schema via Spring / Hibernate 질문을 보았습니다 . 여기에서는 적용 할 수 없습니다.)

H2에 연결시 스키마를 자동 생성 할 수있는 설정이 있는지 알고 싶습니다. 도움이된다면 인 메모리 케이스에만 관심이 있습니다.

H2는 URL 끝에 세미콜론으로 구분 된 다양한 수정자를 지원하지만 스키마를 자동으로 생성하기위한 수정자를 찾지 못했습니다. 그런 기능이 있습니까?

답변:


175

예, 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필요합니다.


대단히 감사합니다. (우수한) 문서에서 어떻게 놓쳤는 지 모르겠습니다.
Laird Nelson

감사합니다. 생성 된 xml에 스키마 이름을 사용하는 liquibase에서 생성 된 변경 집합을 사용하면서 작업을 수행했습니다.
Jaime Hablutzel 2011

2
H2를 최대 절전 모드로 사용하고 RUNSCRIPT 를 호출하여 여러 스크립트를 실행하려면 삼중 백 슬래시 (\\\)를 입력해야합니다. 예를 들어, <property name="hibernate.connection.url">jdbc:h2:mem:test;INIT=RUNSCRIPT FROM 'script1.sql'\\\;RUNSCRIPT FROM script2.sql'</property>최대 절전 설정에서 설정해야합니다 .
Johnny

@Johnny 확실합니까? ;이스케이프 처리 할 필요가없는 것 같습니다 ( ;앞에 이스케이프 처리되지 않은 항목 이 있음 INIT). 백 슬래시를 하나만 사용하면 시도해 볼 수 있습니까? 'script1.sql'\;RUNSCRIPT...
Thomas Mueller


16

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 일 동안 코드가 작동하지 않는 문제를 해결했습니다.
Deepboy

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


8

"기본적으로 응용 프로그램이 호출 DriverManager.getConnection(url, ...)되고 URL에 지정된 데이터베이스가 아직 존재하지 않으면 새 (빈) 데이터베이스가 생성됩니다."— H2 데이터베이스 .

부록 : @Thomas Mueller는 연결 에서 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);
        }
    }
}

예, 그 안에있는 스키마 가 아니라 카탈로그 또는 데이터베이스 입니다. 예를 들어 jdbc : h2 : mem : test에 대한 연결을 열 수 있지만 기본적으로 PUBLIC 스키마에 배치되고 다른 스키마는 존재하지 않습니다.
Laird Nelson

1

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;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.