如何配置spring-boot以使用基于文件的H2数据库

时间:2016-06-19 01:18:17

标签: spring-boot h2

我已经成功创建了一个在内存中使用H2嵌入式数据库的spring启动应用程序。我现在想将其更改为基于文件的版本,该版本将持续存在。

我尝试更改spring.datasource.*文件中的application.properties属性,它们看起来像这样:

spring.datasource.url=jdbc:h2:file:~/test;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.driverClassName=org.h2.Driver`  

看起来像spring boot只是忽略了这些设置,因为它只是按如下方式启动:

o.s.j.d.e.EmbeddedDatabaseFactory        : Starting embedded database: url='jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'

我的pom.xml包含以下可能与此帖相关的依赖项:

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.3.5.RELEASE</version>
</parent>
....
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency> 
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
</dependency>

我从文档和一些帖子中了解到,配置应该正常工作,但对我来说没有运气。只是为了防止我尝试过的一些基本错误并检查以下内容:

  1. 我的应用程序属性位于classspath中:
  2. 我尝试在注释@EnableAutoConfiguration
  3. 中排除自动配置
  4. 我尝试使用注释dataSource@Primary的组合注入@ConfigurationProperties(prefix = "spring.datasource") bean,并使用DataSourceBuilder以编程方式设置属性。这会导致与类型null相关的其他错误。
  5. 似乎我错过了一个关键概念或其他东西。谁能帮忙。

    更新1:从我的自动配置报告中提取:

    Positive matches:
    -----------------
    
        DataSourceAutoConfiguration matched
      - @ConditionalOnClass classes found: javax.sql.DataSource,org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)
    
       DataSourceAutoConfiguration.DataSourceInitializerConfiguration matched
      - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer; SearchStrategy: all) found no beans (OnBeanCondition)
    
       DataSourceAutoConfiguration.EmbeddedConfiguration matched
      - embedded database H2 detected (DataSourceAutoConfiguration.EmbeddedDataSourceCondition)
      - @ConditionalOnMissingBean (types: javax.sql.DataSource,javax.sql.XADataSource; SearchStrategy: all) found no beans (OnBeanCondition)
    
       DataSourceAutoConfiguration.JdbcTemplateConfiguration matched
      - existing auto database detected (DataSourceAutoConfiguration.DataSourceAvailableCondition)
    
       DataSourceAutoConfiguration.JdbcTemplateConfiguration#jdbcTemplate matched
      - @ConditionalOnMissingBean (types: org.springframework.jdbc.core.JdbcOperations; SearchStrategy: all) found no beans (OnBeanCondition)
    
       DataSourceAutoConfiguration.JdbcTemplateConfiguration#namedParameterJdbcTemplate matched
      - @ConditionalOnMissingBean (types: org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; SearchStrategy: all) found no beans (OnBeanCondition)
    
       DataSourceTransactionManagerAutoConfiguration matched
      - @ConditionalOnClass classes found: org.springframework.jdbc.core.JdbcTemplate,org.springframework.transaction.PlatformTransactionManager (OnClassCondition)
    
       DataSourceTransactionManagerAutoConfiguration.TransactionManagementConfiguration matched
      - @ConditionalOnMissingBean (types: org.springframework.transaction.annotation.AbstractTransactionManagementConfiguration; SearchStrategy: all) found no beans (OnBeanCondition)
    
        H2ConsoleAutoConfiguration matched
      - @ConditionalOnClass classes found: org.h2.server.web.WebServlet (OnClassCondition)
      - found web application StandardServletEnvironment (OnWebApplicationCondition)
      - matched (OnPropertyCondition)
    
       HibernateJpaAutoConfiguration matched
      - @ConditionalOnClass classes found: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,org.springframework.transaction.annotation.EnableTransactionManagement,javax.persistence.EntityManager (OnClassCondition)
      - found HibernateEntityManager class (HibernateJpaAutoConfiguration.HibernateEntityManagerCondition)
    
    Negative matches:
    -----------------
    
        DataSourceAutoConfiguration.NonEmbeddedConfiguration did not match
      - missing supported DataSource (DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition)
    

    `

    更新2:添加执行器并查看端点/configprops。这里有趣的是我的配置已经被采用并且数据库存在但是当应用程序运行时它不使用这个dataSource

    "spring.datasource.CONFIGURATION_PROPERTIES":
        {"prefix":"spring.datasource",
         "properties":{
            "schema":null,
            "data":null,
            "xa":{"dataSourceClassName":null,
                   "properties":{}
                 },
            "type":null,
            "separator":";",
            "url":"jdbc:h2:file:~/test;DB_CLOSE_ON_EXIT=FALSE",
            "platform":"all",
            "continueOnError":false,
            "jndiName":null,               
            "sqlScriptEncoding":null,
            "password":"******",
            "name":"testdb",
            "driverClassName":"org.h2.Driver",
            "initialize":true,
            "username":"test"
            }
        }  
    

6 个答案:

答案 0 :(得分:28)

请参阅http://www.h2database.com/html/cheatSheet.html

我想这可能是jdbc.url的问题,请改变它:

# from:
spring.datasource.url=jdbc:h2:file:~/test;DB_CLOSE_ON_EXIT=FALSE

# to:
spring.datasource.url=jdbc:h2:~/test;DB_CLOSE_ON_EXIT=FALSE

答案 1 :(得分:28)

我正在添加这个答案,以避免混淆和进一步的研究。

实际上我遇到了同样的问题,并没有一个答案完全适合我,而不是一些答案的混合。

这是在春季启动时持久存在H2 db所需的最小配置。

application.xml中

# H2
spring.h2.console.enabled=true
spring.h2.console.path=/h2
# Datasource
spring.datasource.url=jdbc:h2:file:~/spring-boot-h2-db
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.hibernate.ddl-auto=update

这里spring.jpa.hibernate.ddl-auto=update可以解决问题。不需要其他任何东西。

无需在pom.xml中添加spring-boot-starter-jdbc

无需在jdbc url中添加任何参数。

答案 2 :(得分:2)

在application.properties上使用以下设置,即使在关闭并重新启动SpringBoot之后,甚至在重新启动计算机之后,我仍设法保持数据的持久性。

spring.datasource.name=japodb
spring.datasource.initialize=false
spring.datasource.driverClassName=org.h2.Driver

spring.datasource.url=jdbc:h2:file:~/japodb;DB_CLOSE_ON_EXIT=FALSE;IFEXISTS=TRUE;DB_CLOSE_DELAY=-1;

当VM退出时不要关闭数据库,是的,但是如果它已经存在,也不要建立新的数据库。

jdbc:h2:<url>;IFEXISTS=TRUE

spring.jpa.hibernate.ddl-auto = update

答案 3 :(得分:1)

这是对我有用的配置

#File based h2 DB
spring.datasource.url=jdbc:h2:file:C:/temp/test_db;DB_CLOSE_ON_EXIT=FALSE;AUTO_RECONNECT=TRUE;DB_CLOSE_DELAY=-1
#In memory
#spring.datasource.url=jdbc:h2:mem:testdb:security_permission;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.jpa.hibernate.ddl-auto=update
spring.datasource.username=user
spring.datasource.password=admin
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
#Use datasource.initialization-mode if you are configured to use file based h2 and data.sql
spring.datasource.initialization-mode=always

当我使用data.sql进行数据初始化时,我必须使用以下选项才能使其工作

spring.datasource.initialization-mode=always

答案 4 :(得分:0)

刚刚使用带有一些依赖项h2, JPA, web, devtools, actuator的start.spring.io生成了一个全新的Spring Boot项目。添加一个简单的Entity和Spring Data存储库后,默认情况下确实在内存中创建了数据库。

将以下内容添加到我的application.properties中肯定会在正确的位置创建数据库文件:

spring.datasource.url=jdbc:h2:file:~/test;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.driverClassName=org.h2.Driver

当启用devtools http://localhost:8080/h2-console/时,我甚至可以使用H2控制台连接到它。

下一个逻辑步骤是访问http://localhost:8080/autoconfig端点并检查自动配置状态。

就我而言,以下是positiveMatches

DataSourceAutoConfiguration.NonEmbeddedConfiguration: [
{
  condition: "DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition",
  message: "supported DataSource class found"
},
{
  condition: "OnBeanCondition",
  message: "@ConditionalOnMissingBean (types: javax.sql.DataSource,javax.sql.XADataSource; SearchStrategy: all) found no beans"
}
],

以及negativeMatches中的以下内容:

DataSourceAutoConfiguration.EmbeddedConfiguration: [
{
  condition: "DataSourceAutoConfiguration.EmbeddedDataSourceCondition",
  message: "existing non-embedded database detected"
}
],

您可以尝试以下操作并检查自动配置报告吗?

答案 5 :(得分:-2)

在您的类路径中创建一个 .h2.server.properties 文件并放在下面并重试。您可以在资源文件夹中创建此文件。

__global__ void test(float* result, float a, float b) {
  float r_add = 0, r_div = 1;

  long long t1 = clock64();
#pragma unroll
  for (int i = 0; i < 500; i++) {
    r_add += a;
    r_add += b;
  }
  long long t2 = clock64();
#pragma unroll
  for (int i = 0; i < 500; i++) {
    r_div /= a;
    r_div /= b;
  }
  long long t3 = clock64();
  long long t4 = clock64();

  result[0] = (t2 - t1) - (t4 - t3);
  result[1] = (t3 - t2) - (t4 - t3);
  result[2] = float(t3 - t2 - (t4 - t3)) / float(t2 - t1 - (t4 - t3));
  result[3] = t4 - t3;
  result[4] = r_add;
  result[5] = r_div;
}