क्या मेरे पास इन-मेमोरी डेटाबेस में H2 ऑटोक्रीट हो सकता है?


93

(मैंने पहले ही H2 डेटाबेस को मेमोरी में देखा है - स्प्रिंग / हाइबरनेट प्रश्न के माध्यम से इनिट स्कीमा ; यह यहां लागू नहीं है।)

मैं जानना चाहता हूं कि क्या H2 में कोई सेटिंग है जो मुझे इसे कनेक्ट करने पर एक स्कीमा ऑटो बनाने की अनुमति देगा। यदि यह मदद करता है, तो मुझे केवल इन-मेमोरी केस में दिलचस्पी है।

H2 URL के अंत में विभिन्न अर्धविराम से अलग किए गए संशोधक का समर्थन करता है, लेकिन मुझे स्कीमा बनाने के लिए स्वचालित रूप से एक नहीं मिला। क्या ऐसी कोई विशेषता है?

जवाबों:


171

हाँ, 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'";

कृपया ध्यान दें कि डबल बैकस्लैश ( \\) केवल जावा में आवश्यक है। बैकस्लैश (ते) से पहले ;के भीतर INITआवश्यक है।


आपका बहुत बहुत धन्यवाद; सुनिश्चित नहीं है कि मैं कैसे (उत्कृष्ट) प्रलेखन में चूक गया।
लेयर्ड नेल्सन

धन्यवाद, इसने काम बना दिया क्योंकि मैं लिबास से उत्पन्न बदलावों का उपयोग कर रहा था जो उत्पन्न किए गए xml के लिए स्कीमा नाम का उपयोग करते हैं।
Jaime Hablutzel

2
ध्यान दें कि यदि आप हाइबरनेट के साथ H2 का उपयोग करते हैं और RUNSCRIPT पर कॉल करके कई स्क्रिप्ट चलाना चाहते हैं , तो आपको ट्रिपल बैकस्लैश (\\\) टाइप करना चाहिए। उदाहरण के लिए, आपको <property name="hibernate.connection.url">jdbc:h2:mem:test;INIT=RUNSCRIPT FROM 'script1.sql'\\\;RUNSCRIPT FROM script2.sql'</property>अपने हाइबरनेट कॉन्फ़िगरेशन में सेट करना चाहिए ।
जॉनी

@ जॉनी क्या आपको यकीन है? ऐसा लगता है कि ;भागने की जरूरत नहीं है ( ;इससे पहले एक अनसैप्ड है INIT)। यदि आप केवल एक बैकस्लैश कार्यों का उपयोग करके प्रयास कर सकते हैं? 'script1.sql'\;RUNSCRIPT...
थॉमस मुएलर


14

यदि आप application.yml के साथ स्प्रिंग का उपयोग कर रहे हैं तो निम्नलिखित आपके लिए काम करेगा

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



1
आपका बहुत बहुत धन्यवाद। मैंने इस टिप का उपयोग एक समस्या को ठीक करने के लिए किया था जिससे मेरा कोड 4 दिनों तक काम नहीं कर रहा था।
दीपबॉय

9

थॉमस ने जो लिखा है वह सही है, इसके अलावा, यदि आप कई स्कीमाओं को शुरू करना चाहते हैं तो आप निम्नलिखित का उपयोग कर सकते हैं। ध्यान दें \\;कि दो क्रिएट स्टेटमेंट को अलग करना है।

    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 में निर्दिष्ट अभी तक मौजूद नहीं है, एक नया (खाली) डेटाबेस बनाया जाता है।" - एच 2 डाटाबेस

परिशिष्ट: @ थोमस म्यूएलर दिखाता है कि कनेक्शन पर एसक्यूएल को कैसे निष्पादित किया जाए , लेकिन मैं कभी-कभी कोड बनाता हूं और कोड में पॉपुलेट करता हूं, जैसा कि नीचे दिया गया है।

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 के लिए एक कनेक्शन खोल सकते हैं, लेकिन डिफ़ॉल्ट रूप से आपको सार्वजनिक स्कीमा में रखा जाता है, और कोई अन्य स्कीमाता मौजूद नहीं है।
लेयर्ड नेल्सन

0

यदि आप स्प्रिंग फ्रेमवर्क का उपयोग कर रहे हैं application.ymlऔर परीक्षण को INITसंपत्ति पर एसक्यूएल फ़ाइल खोजने में परेशानी हो रही है , तो आप classpath:नोटेशन का उपयोग कर सकते हैं ।

उदाहरण के लिए, यदि आपके पास init.sqlSQL फ़ाइल है src/test/resources, तो उपयोग करें :

url=jdbc:h2:~/test;INIT=RUNSCRIPT FROM 'classpath:init.sql';DB_CLOSE_DELAY=-1;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.