如何配置弹簧启动使用基于文件的 H2数据库

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

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

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. 我的应用程序属性位于类路径中:
  2. 我试图在注释 @EnableAutoConfiguration中排除自动配置
  3. 我曾经尝试过注入一个 dataSource bean,其中包含注释 @Primary@ConfigurationProperties(prefix = "spring.datasource")和用 DataSourceBuilder以编程方式设置属性的组合。这会导致与 null类型相关的其他错误。

我好像漏掉了一个关键概念什么的,有人能帮忙吗。

更新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"
}
}
104270 次浏览

在类路径中创建一个文件 . h2.server.properties,然后放在下面,再试一次。可以在“资源”文件夹中创建此文件。

#H2 Server Properties
0=H2 File|org.h2.Driver|jdbc\:h2\:file\:~/test;DB_CLOSE_ON_EXIT=FALSE


# Enable if you want other applications to connect
#webAllowOthers=true
#webPort=8082
#webSSL=false

刚刚使用 start.Spring.io 生成了一个全新的 Spring Boot 项目,其中包含一些依赖项 h2, JPA, web, devtools, actuator。在添加一个简单的 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"
}
],

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

请参阅 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

通过对 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

我添加这个答案是为了避免混淆和进一步的研究。

事实上我也有同样的问题,没有一个答案对我来说是完全有效的,只有一些答案的组合起作用了。

下面是在春季启动中持久化 H2db 所需的最小配置。

应用性能

# 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

不需要在 jdbcurl 中添加任何参数。

下面是为我工作的配置

#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
spring.jpa.defer-datasource-initialization=true

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

spring.datasource.initialization-mode=always

数据初始化后,可以将其设置为 never

spring.datasource.initialization-mode=never