在运行时从头开始建立数据库

时间:2019-06-29 12:42:35

标签: java persistence h2 jooq flyway

我目前正在开发一个我希望完全独立的Java数据库应用程序(即单个.jar文件和一个配置文件,仅此而已)。这是一个非常小的项目,并且我没有像商业代码库那样花哨的构建管道和额外的应用程序数据,因此,我需要一个简单的单罐解决方案。

实现此目标的一部分涉及在应用程序中嵌入H2并在运行时设置数据库。但是,我不确定在此用例中如何应用所需的架构。让我们以该表为例。

+-------------+------------+----------+---------+
| Column name | Data type  | Nullable | Default |
+-------------+------------+----------+---------+
| id          | BIGINT     | FALSE    | -       |
| prefix      | VARCHAR(3) | FALSE    | 'g!'    |
+-------------+------------+----------+---------+

到目前为止,这是我的两个解决方案。

通过jOOQ以编程方式布置表格

try (DSLContext ctx = DSL.using(dataSource, SQLDialect.MYSQL)) {
    ctx.createTableIfNotExists("guilds")
        .column("id", SQLDataType.BIGINT.nullable(false))
        .column("prefix", SQLDataType.VARCHAR(3).nullable(false).defaultValue("g!"))
        .constraint(constraint("PK_GUILDS").primaryKey(field("id")))
        .execute();
}

自然,在这种使用情况下,我无法使用jOOQ的代码生成,因为没有什么可为其生成类的。这是可行的,并且完全是编程的,但是它确实很丑陋,并且使用静态导入阻塞了类。对其进行扩展以添加更多的表和/或列很痛苦,并且使代码的可读性甚至更低。

我尝试过的另一件事是Flyway,它非常简单,并不可怕。我需要的只是一个小的.sql文件,它可以设置我的架构,如下所示:

create table guilds(
    id BIGINT NOT NULL,
    prefix VARCHAR(3) NOT NULL,
    PRIMARY KEY(id)
);

然后,我可以运行Gradle任务来生成一个空的H2数据库,其中所有表都已设置好并可以使用。 Gradle甚至允许我指定要在构建之前运行的任务。在这种情况下,我还可以使用jOOQ代码生成,这使得事情的 lot 更加容易。不过,所有这些都在编译时发生,据我所知,我必须将应用程序与一个空的数据库文件打包在一起。当然,这并不能满足我最初想要的单一罐子需求。

是否有一种干净的“常规”方式来执行此操作,或者以这种方式构建应用程序只是没有涉及数据库的任何人所做的事情?

2 个答案:

答案 0 :(得分:1)

您应该使用Spring–Data并让它为您完成工作。在应用程序属性中,您可以设置数据源。您创建您的实体(带注释的类)和您的存储库。完成并假装您正在使用休眠模式后,您只需在应用程序属性中放入"hibernate.hbm2ddl.auto", "create-drop"之类的属性即可。这将自动为您创建并删除数据库。无需额外的代码。还有更多这样的配置选项。您会在手册中找到它们。

答案 1 :(得分:1)

从jOOQ的角度来看,我们强烈建议您选择Flyway approach或类似的名称。这样做的原因是,随着项目的发展,您会很高兴选择一种可以完全控制架构演变的路径,而不是让第三方产品为您管理,并且jOOQ集成可以轻松进行。

您曾经尝试过的jOOQ DDL API也可以正常工作,例如当您将此API与Flyway或类似programmatic schema evolution API一起使用时。即使您有多个模块作为输入,仍可以将单个jar作为输出生成。例如,您可以使用maven-assembly-plugin来生产这个罐子。这种特殊的构建约束不应成为决定如何管理数据库架构的驱动因素。