[spring-projects/spring-boot]Spring Boot、flyway 和 jooq 集成

2024-05-09 418 views
2

几个月前,当我开始一个新建项目时,我想到使用 Flyway 和 jooq 进行数据库模式管理和 ORM。很快就发现,虽然 Flyway 与 spring-boot 的集成非常酷 - 只需向类路径添加适当的依赖项,它就可以开箱即用 - 它与 jooq 不同。

使用 jooq 我需要:

  1. 将插件添加到我的构建工具(本例中为 gradle)以生成类
  2. 也将 Flyway 移动到构建工具 - 因为在启动时迁移架构已经太晚了
  3. 在构建工具和应用程序本身中保留数据库连接详细信息(用户、密码) - 两者都需要访问权限

理想情况下,最好将 jooq 和 Flyway 放在类路径上,并且两个库可以一起工作。老实说,我什至不确定这是否可能,因为数据库类将在应用程序启动时动态生成,因此它们还需要添加到类路径中。更重要的是,设置开发环境也可能存在问题。

也就是说,我想知道你对此有什么计划或想法吗?

回答

0

@lukaseder 和 @michael-simons 可能对此有想法,但根据我有限的理解,jOOQ 需要尽早生成类,以便您可以在自己的代码中引用它们。

如果有什么我们可以轻松做的事情会有所帮助,我们显然会考虑它,我只是不知道那会是什么。

4

感谢您的及时回复@philwebb!这就是我在说我不知道​​这是可能的时候的想法;)

1

我将对此进行标记,waiting-for-feedback看看是否有任何建议。如果没有人发表评论,GitHub 机器人将在几周后关闭该问题。

0

我已经和卢卡斯谈过了,所以我想他会提供一些意见。

2

嘿大家。我记得这个问题不久前就已经出现了。

Flyway 与 jOOQ 相比,不适用于运行时以及构建时间。

jOOQ 在构建期间用作代码生成器。结果就是我所说的基于 Java 的模式。请参阅我的这张幻灯片:https://speakerdeck.com/michaelsimons/live-with-your-sql-fetish-and-choose-the-right-tool-for-the-job ?slide=26 。

这个想法是根据这个“模式”进行编码,即:使用类来编写类型安全的 SQL。

在启动时生成这些类是没有意义的,除了可能会遇到错误(例如生成 Java 模式后数据库已发生变化)。但是,如果您的组织/项目允许的话,我强烈建议在构建运行时使用迁移工具。

这是一个视频,展示了我的方法https://www.youtube.com/watch?v=4pwTd6NEuN0,代码位于https://github.com/michael-simons/bootiful-databases。我在这里为即将出版的 Spring Boot 书籍提供了另一个演示https://github.com/springbootbuch/database_examples

不,我不隶属于 jOOQ,我只是碰巧非常喜欢它及其背后的想法。另外,卢卡斯也很有趣。

5

谢谢@迈克尔-西蒙斯!我认为我们可以轻松地改善构建时体验的事情并不多,并且仅在运行时生成 jOOQ 类也没有多大意义。我现在要关闭这个问题。谢谢!

7

@michael-simons 感谢您的意见!我认为——也许并不是说它毫无意义——而是有问题且难以实施。感谢您提供的材料。一定会看的。

看来我需要将部署过程更改为:

  1. 迁移
  2. 产生
  3. 启动运行

那是对的吗?另外,您提到在构建运行时运行迁移。在这个特定的示例中,会有用于 Flyway 迁移的 gradle 任务,并且 Flyway 也会添加到项目类路径中吗?

2

你好@Opalo 是的,这将是最适合专用开发人员数据库的建议,无论如何这是一个好主意。这样你就可以确保

  • 迁移确实有效
  • 您使用适合该架构的 jOOQ 代码
  • Prod 数据库可以处于不同的迁移级别,因此您也需要更新!

有一些选项可以做到这一点。 Spring Boot 甚至支持允许进行架构更改的 Flyway 任务的不同数据库用户。配置产品中使用的最好的方法是从 Vault 或 ConfigServer 获取凭据。

关于flyway和gradle:我还没有这方面的经验。

6

另外,卢卡斯也很有趣。

你这么说只是因为你知道我在潜伏,而且你想要另一件 T 恤。 ;-)

虽然我同意 jOOQ 代码生成在生产中可能没有意义,但它在 CI(包括集成测试)中确实有意义。例如,如果有人删除了一列,那么如果 CI 已经因编译错误而提前失败,那将是很好的,因为在没有该列的情况下重新生成了 jOOQ 代码,而代码中仍然引用了该列。

如果这些事情是手动完成的,jOOQ可以很容易地与flyway集成: https://blog.jooq.org/2014/06/25/flyway-and-jooq-for-unbeatable-sql-development-productivity

本质上,如果项目同时使用 jOOQ 和 Flyway,则可能会SchemaVersionProvider自动配置 jOOQ,它会检查 Flyway 的"schema_version"表是否有任何更新,并仅在此类更新可用时重新生成代码。这有助于减少较大架构的构建时间。 (请注意,无论如何,相同的类都不会被重写以支持增量编译,但内存中代码生成仍在发生)

现在,我不知道 Spring Boot 是否可以合理地利用这种自动集成。

3

从它的价值来看:我的一个项目还结合了臭名昭著的三重弹簧靴、flyway 和最后但并非最不重要的 jOOQ。我花了很长时间才弄清楚这一切,但现在它正在按照我的意愿运行。配置主要在构建工具方面,我认为 Spring Boot 也没有太大的潜力来使这变得更容易。

与 @lukaseder 和 @michael-simons 引用的示例类似(并且受到启发 - 谢谢大家!),我的方法具有以下特征:

  • 在maven构建期间,flyway-maven-plugin首先更新数据库模式,然后jooq-codegen-maven-plugin生成包含在使用maven构建的artefact中并附带的类。
  • Properties-maven-plugin 有助于不必多次配置数据库连接详细信息。
  • 一旦构建的工件在生产中启动,flyway 就会开始更新数据库(如果需要)。如果成功,数据库应该与 jOOQ 在构建期间生成的类相匹配。
  • 我正在 CI 服务器上的专用数据库上运行集成测试。

我使用 Maven 作为构建工具。不知道如何使用 gradle 或其他构建工具来实现这一点。

该项目可以在这里找到:https://github.com/ursjoss/scipamato。相关模块之一是例如 scipamato-core-persistence-jooq

干杯,乌尔斯

0

很高兴在这里见到你,@ursjoss :)

我认为 Spring Boot 也没有太大的潜力让这一切变得更容易。

但是您是否看到了 Flyway 或 jOOQ Maven / Gradle 插件的潜力?

7

很高兴在这里见到你,@ursjoss :)

同样,卢卡斯:-)

恕我直言,所有部分都做了他们应该做的事情:

  • Flyway-maven-plugin 可以很好地管理数据库迁移。我们只需要在 jOOQ maven 插件启动之前(在生成源阶段)指示它完成它的工作。
  • jooq-codegen-maven 插件做了它应该做的事情并负责。
  • Spring Boot 在运行时集成 Flyway 和 jOOQ 方面做得很好 - 考虑到构建工具正确管理依赖关系(我刚刚在创业之初的周末删除了一些 jOOQ 配置类。我意识到它们是不必要)。

乏味的事情只是在 Maven(或任何构建工具)中调整所有这些和平。

我唯一能想到的就是将这个maven-wizardry封装到一些封装的pom/bom中,无论maven“单元”是什么。不确定这是否可以用于插件配置......

3

@ursjoss 您能否详细说明一下部署是如何完成的?您是否部署了一个构建的工件(jar 文件),该工件在其类路径中具有 Flyway 并进行模式迁移?或者是通过构建工具完成迁移的?

5

@Opalo我正在分发最后的胖罐子,其中包含包括飞行路线在内的所有内容。应用程序启动后,flyway 就会启动,从 application.properties 文件中读取 Flyway 属性(url、用户、密码),并检查是否存在尚未应用的迁移。如果是这样,它会及时运行它们,以便实际应用程序能够使用预编译的 jOOQ 类(这些类是由 maven 基于本地数据库中的迁移环境预先构建的)以及现在应该与jOOQ 课程。

有关 Flyway 集成,请参阅https://flywaydb.org/documentation/plugins/springboot

在我的情况下,需要一些技巧来避免在我的开发人员机器上的集成测试期间运行 Flyway,但在持续集成期间仍然运行它。但是 Spring Boot 在使用不同的 application.property 文件(在我的例子中涉及 spring 配置文件)的整个属性解析方面做得很好。

我的文档并未涵盖您的问题中的这些详细信息,但您可能会在这些页面上发现一些有趣的内容:

也许在项目本身。

HTH-- 乌尔斯干杯