【问题标题】:Setup H2 in Server Mode using Java Based Configuration使用基于 Java 的配置在服务器模式下设置 H2
【发布时间】:2013-12-08 00:57:06
【问题描述】:

我有 spring XML,它使我能够使用以下配置以服务器模式启动 H2 数据库:

<beans profile="test-h2">
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close">
        <property name="driverClassName" value="org.h2.Driver"/>
        <property name="url" value="jdbc:h2:target/h2/pps;AUTO_SERVER=TRUE"/>
        <property name="username" value="sa"/>
        <property name="password" value=""/>
    </bean>
    <bean id="entityManagerFactory" parent="entityManagerFactoryCommonParent">
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>

我想转换为基于 java 的配置。我在这里似乎有一个帖子:Start and setup in-memory DB using Spring 问了同样的问题,我查看了嵌入式数据库的http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/jdbc.html#jdbc-embedded-database-support,但它没有说明如何将 H2 模式设置为服务器模式。它仅在“mem”模式下为我启动服务器。

我有以下代码:

EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();

builder.setType(EmbeddedDatabaseType.H2);
builder.setName(DATABASE_NAME);
builder.addScript(H2_SCHEMA);
builder.addScript(H2_TEST);
return builder.build();

也许使用 EmbeddedDatabaseBuilder(ResourceLoader) 可能会起作用。有人有一些示例代码吗?

【问题讨论】:

    标签: java spring hibernate configuration h2


    【解决方案1】:

    这是允许您使用基于 java 的 spring 配置以服务器模式启动 H2 数据库的代码:

    private static final String H2_JDBC_URL_TEMPLATE = "jdbc:h2:%s/target/db/sample;AUTO_SERVER=TRUE";
    @Value("classpath:seed-data.sql")
    private Resource H2_SCHEMA_SCRIPT;
    
    @Value("classpath:test-data.sql")
    private Resource H2_DATA_SCRIPT;
    
    @Value("classpath:drop-data.sql")
    private Resource H2_CLEANER_SCRIPT;
    
    
    @Bean
    public DataSource dataSource(Environment env) throws Exception {
            return createH2DataSource();
    }
    
    
    @Autowired
    @Bean
    public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
    
        final DataSourceInitializer initializer = new DataSourceInitializer();
        initializer.setDataSource(dataSource);
        initializer.setDatabasePopulator(databasePopulator());
        initializer.setDatabaseCleaner(databaseCleaner());
        return initializer;
    }
    
    
    private DatabasePopulator databasePopulator() {
        final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
        populator.addScript(H2_SCHEMA_SCRIPT);
        populator.addScript(H2_DATA_SCRIPT);
        return populator;
    }
    
    private DatabasePopulator databaseCleaner() {
        final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
        populator.addScript(H2_CLEANER_SCRIPT);
        return populator;
    }
    
    private DataSource createH2DataSource() {
        String jdbcUrl = String.format(H2_JDBC_URL_TEMPLATE, System.getProperty("user.dir"));
        JdbcDataSource ds = new JdbcDataSource();       
        ds.setURL(jdbcUrl);
        ds.setUser("sa");
        ds.setPassword("");
    
        return ds;
    }
    
    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory);
        return transactionManager;
    }
    
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(Environment env) throws Exception {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(Boolean.TRUE);
        vendorAdapter.setShowSql(Boolean.TRUE);     
    
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setPersistenceUnitName("sample");
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("com.sample.model");
        factory.setDataSource(dataSource(env));     
    
        factory.setJpaProperties(jpaProperties());
        factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
    
        return factory;
    }
    
    Properties jpaProperties() {
        Properties props = new Properties();
        props.put("hibernate.query.substitutions", "true 'Y', false 'N'");
        props.put("hibernate.hbm2ddl.auto", "create-drop");
        props.put("hibernate.show_sql", "false");
        props.put("hibernate.format_sql", "true");
    
        return props;
    }
    

    【讨论】:

    • 到目前为止 - 这完全是矫枉过正。同样的事情可以用几行来完成。 springframework.guru/…我与作者没有任何关系 - 但他的指示确实对我有用。
    【解决方案2】:

    我相信这是不可能的。术语嵌入式数据库在不需要服务器的数据库中,并且嵌入在应用程序中,因此您不应为此使用 EmbeddedDatabase。

    在 h2 文档中,术语“嵌入式”被“本地”迷住了 - (连接到嵌入式(本地)数据库),当他们使用“服务器”时,他们谈论远程连接,其中数据库由服务器管理。为了强化这一想法,EmbeddedDataSource 接口仅添加了一个数据源“shutdown”接口中不存在的方法,该方法通常用于在应用程序关闭时关闭数据库,例如通过@Bean(destroyMethod="shutdown")

    在此处查看更多详细信息:

    http://h2database.com/html/features.html#database_url

    When is a database called as an Embedded database?

    http://docs.spring.io/spring/docs/3.0.x/api/org/springframework/jdbc/datasource/embedded/EmbeddedDatabase.html

    【讨论】:

      猜你喜欢
      • 2012-06-06
      • 1970-01-01
      • 2021-01-04
      • 1970-01-01
      • 2013-01-24
      • 2012-05-19
      • 2012-08-20
      • 2020-04-17
      • 1970-01-01
      相关资源
      最近更新 更多