首页 > 解决方案 > 在运行时从头开始设置数据库

问题描述

我目前正在开发一个想要完全独立的Java 数据库应用程序(即单个.jar 文件和一个配置文件,仅此而已)。这是一个非常小的项目,我没有像商业代码库那样花哨的构建管道和额外的应用程序数据 - 因此需要一个简单的单 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 代码生成,这让很多事情变得更容易。不过,这一切都发生在编译时,据我所知,我必须将应用程序与一个空的数据库文件打包在一起。当然,这并不能满足我最初想要的单罐愿望。

是否有一种干净的“传统”方式来做到这一点,或者以这种方式构建应用程序只是在涉及数据库时不是任何人都会做的事情?

标签: javapersistenceh2jooqflyway

解决方案


从 jOOQ 的角度来看,我们强烈建议您选择Flyway方法或类似的方法。这样做的原因是,当您的项目增长时,您会很高兴选择一条完全控制模式演变的路径,而不是让第三方产品为您管理,并且 jOOQ 集成可以毫不费力地工作.

当然,您之前尝试过的 jOOQ DDL API 也可以正常工作,例如,当您将此 API 与 Flyway 或类似于编程模式演变API 的东西一起使用时。即使您有多个模块作为输入,您仍然可以生成单个 jar 作为输出。例如,您可以使用maven-assembly-plugin来生成这个单一的 jar。这个特定的构建约束不应该是您决定如何管理数据库模式的驱动因素。


推荐阅读