Spring Boot / JPA / Hibernate,如何根据 Spring 配置文件切换数据库供应商?

Posted

技术标签:

【中文标题】Spring Boot / JPA / Hibernate,如何根据 Spring 配置文件切换数据库供应商?【英文标题】:Spring Boot / JPA / Hibernate, How to switch database vendor according to Spring profile? 【发布时间】:2017-02-13 13:32:54 【问题描述】:

我正在使用 Spring Boot/JPA/Hibernate。我想在 localhost 上测试时使用 HSQLDB,在服务器上部署时使用 mysql

在 pom.xml 中,我对 MySQL 有这个依赖:

 <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
 </dependency>

以及对 HSQLDB 的依赖:

<dependency>
   <groupId>org.hsqldb</groupId>
   <artifactId>hsqldb</artifactId>
</dependency>

由于 Spring Boot 自动配置,我可能无法将这两个依赖项都放在 pom.xml 中。但是我想在local Spring 配置文件处于活动状态时使用 HSQLDB,并在 server Spring 配置文件处于活动状态时使用 MySQL。理想情况下,我想只生成一个war文件并使用mvn spring-boot:run运行本地版本,然后从war文件部署服务器版本。

有什么想法吗?

P.S.:我正在使用 maven

【问题讨论】:

如果两个依赖项都设置了,你会遇到什么问题?应用程序是否未正确启动?或者别的什么 也许您可以在应用程序中实现两个不同的数据源,并让配置文件值决定使用哪个数据源。 @Patrick 经过一番调查,我发现问题出在 MySQL 和 HSQLDB 之间的 sql 方言不兼容,但 Stephane Nicoll 是对的,在 pom.xml 中同时具有这两个依赖项是没有问题的。 【参考方案1】:

您需要创建一个 Maven 配置文件 而不是 spring 配置文件并相应地添加依赖项。创建具有 hsqldb 依赖项的 local 配置文件并在开发模式下激活它。然后使用 mysql 依赖项创建一个 server 配置文件,并在打包部署到服务器时激活它。我个人更喜欢 devrelease 作为命名约定(但这是我的拙见)。然后你必须用 spring profile

来快捷方式 ma​​ven profile
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>xyz</version>
    <configuration>
      <profiles>
        <profile>local</profile>....

在本地配置文件中和

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>1.4.1.RELEASE</version>
    <configuration>
      <profiles>
        <profile>server</profile>...

在服务器配置文件中并使用此开关运行所需的配置

mvn spring-boot:run -P[local or server]

Introduction to Build Profiles

【讨论】:

这是一个很好的解决方案,但他必须为 test 和 prod 创建两个 war 文件,对吗? @Patrick 这是我们公司项目中使用的解决方案。生产配置文件缩小了 JS 和 CSS 源以改善我们的页面加载时间。我们使用mvn clean package -Prelease 创建产品战争文件。不缩小每个构建也可以节省我们在开发过程中烦人的等待时间。 @patrick 取决于:对于测试和产品,建议使用相同的数据库(所以 mysql)。他必须制造两场战争:一场用于开发,一场用于发布(用于测试和生产)。这就是为什么我建议更改命名约定 @Sammyrulez 实际上,我有三个 Spring 配置文件组合:local 用于在我的本地机器(HSQLDB)上进行测试,server,dev 用于在生产环境(MySQL)上进行测试,server用于在生产环境(MySQL)上部署。 @OrtomalaLokni 弹簧型材还是 maven 型材?抱歉,不清楚【参考方案2】:

由于 Spring Boot 自动配置,我可能无法将这两个依赖项都放在 pom.xml 中。

当然你可以同时拥有它们。有几种解决方案。

最基本的方法是同时拥有两个依赖项,并使用 mysql 数据库的设置在您的项目中创建一个application-server.properties。当您在没有特定配置文件的情况下运行应用程序时,Spring Boot 将找不到任何连接到 MySQL 的信息,因此它将回退到 HSQL。在服务器上部署应用程序时,请确保启用 server 配置文件。相同的工件可用于两种用例。

您可以通过在生成 fat jar 时排除 hsql 依赖项来稍微改进该解决方案。这样做的好处是,如果您忘记启用配置文件,您将在启动时遇到异常,而不是静默使用内存数据库。要排除 hsql,只需 configure the maven plugin。您将能够在本地 (mvn spring-boot:run) 或在您的 IDE 中运行该应用程序,并且 fat jar 将仅包含 mysql 依赖项。不过,您仍然需要启用 server 配置文件。

如果您使用的是战争,则不能使用最后一种解决方案:切换到 jar 的另一个理由 ;-)

【讨论】:

为什么无法从war文件中排除hsql? 你可以。但是,如果您需要运行 war 文件并将其排除在外,您将无法使用内存数据库运行您的应用程序。当你有一个 jar 时,你可以直接从 IDE 运行你的应用程序

以上是关于Spring Boot / JPA / Hibernate,如何根据 Spring 配置文件切换数据库供应商?的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL springboot spring data jpa 集成

JPA/Spring/Hibernate/etc 中是不是有类似于 JPA 的 @PrePersist 允许更改相关实体的功能?

Spring Boot(17)——使用Spring Data JPA

spring boot 系列之四:spring boot 整合JPA

Spring Boot(十五):spring boot+jpa+thymeleaf增删改查示例

spring-data-jpa :找到对集合 org.hibernate.HibernateException 的共享引用