6

使用 play framework 2.1,我试图找到拥有两种不同数据库配置的最佳方式:

  • 一种基于 mysql 运行我的应用程序
  • 一个基于 H2 测试我的应用程序

虽然做其中一个很容易,但当我尝试同时做这两个时会遇到以下问题:

  1. 我不能拥有相同的数据库演变,因为即使在 mysql 模式下,某些 mysql 特定命令也不能与 H2 一起使用:这意味着两组演变和两个单独的数据库名称
  2. 我不确定如何通过另一个保留在测试模式下进行测试来覆盖主 application.conf 文件。我尝试过的(从命令行传递文件名或覆盖键)似乎保留给 prod 模式。

我的问题:任何人都可以推荐一个很好的方法(一直使用mysql,并且只有H2在测试中),而不会使运行应用程序过于复杂吗?谷歌没有帮助我。

谢谢你的帮助。

4

3 回答 3

6

您可能会发现一些有用的技巧。

首先,MySQL 的/*! */符号允许您添加 MySQL 将遵循的代码,但其他 DB 将忽略,例如:

create table Users (
  id bigint not null auto_increment,
  name varchar(40)
) /*! engine=InnoDB */

这不是灵丹妙药,但它可以让您了解 MySQL 和 H2 语法之间的一些差异。这是一个 MySQL 主义,所以它对其他数据库没有帮助,但由于大多数其他数据库不像 MySQL 那样古怪,你可能不需要它——我们将我们的数据库从 MySQL 迁移到 PostgreSQL,它没有支持/*! */符号,但 PostgreSQL 与 H2 足够相似,我们不需要它。

如果你想为 dev 和 prod 使用不同的配置,你可能最好为 prod 提供额外的配置。这样做的原因是您可能会使用 启动您的开发服务器play run,并使用 启动您的产品服务器play stage; target/starttarget/start可以带-Dconfig.resource参数。例如,prod.conf为 prod 创建一个额外的配置文件,如下所示:

include "application.conf"

# Extra config for prod - this will override the dev values in application.conf
db.default.driver=...
db.default.url=...
...

并创建一个start_prod如下所示的脚本:

#!/bin/sh

# Optional - you might want to do this as part of the build/deploy process instead
#play stage
target/start -Dconfig.resource=prod.conf

理论上,你可以反过来做,并application.conf包含 prod conf,并创建一个dev.conf文件,但你可能需要一个脚本来启动 prod(你可能最终需要额外的 JVM/memory/GC参数,或将其添加到 rc.d,或其他)。

于 2013-04-10T09:05:45.633 回答
2

正如您自己写的那样,使用不同的数据库引擎可能是最糟糕的情况:某些功能、保留关键字等方面的差异导致您有时需要编写非常特定于所选数据库引擎的自定义语句。最好使用使用同一引擎的两个单独的数据库。

不幸的是,我不知道配置覆盖的问题,所以如果覆盖配置的默认方式失败......覆盖 application.conf 中的 id - 这样你就可以快速评论整个块......)

于 2013-04-08T18:45:11.003 回答
1

以下是如何在内存数据库中使用测试:

public class ApplicationTest extends WithApplication {
    @Before
    public void setup() {
        start(fakeApplication(inMemoryDatabase("default-test"), fakeGlobal()));
    }

    /// skipped ....
}

inMemoryDatabase() 默认使用 H2 驱动。您可以在源代码中找到更多详细信息

于 2013-04-08T21:27:56.687 回答