可用版本: 开发版 (3.21) | 最新版 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11

运行时目录、模式和表映射

适用于 ✅ 开源版   ✅ 专业版   ✅ 企业版

大多数 SQL 对象类型都带有 org.jooq.Catalogorg.jooq.Schema限定。在多租户应用程序中,用户可能希望将这些标识符命名空间映射到非默认值。

将您的 DEV 模式映射到生产环境

您可能希望以这种方式设计数据库,即拥有多个模式实例。当您希望清晰地分离属于多个客户/组织单位/分支/用户的数据,并将每个实体的数据放入单独的数据库或模式中时,这非常有用。

在我们的 AUTHOR 示例中,这意味着您将为几家公司(如 My Book World 和 Books R Us)提供图书参考数据库。在这种情况下,您可能会有如下的模式设置:

  • DEV:您的开发模式。这将是您进行代码生成的模式,jOOQ
  • MY_BOOK_WORLD:My Book World 的模式实例
  • BOOKS_R_US:Books R Us 的模式实例

使用 jOOQ 将 DEV 映射到 MY_BOOK_WORLD

当 My Book World 的用户登录时,您希望他们使用从 DEV 生成的类来访问 MY_BOOK_WORLD 模式。这可以通过 org.jooq.conf.RenderMapping 类来实现,该类可以配置您的 Configuration 的 设置。请看以下示例:

示例配置

Settings settings = new Settings()
    .withRenderMapping(new RenderMapping()
    .withSchemata(
        new MappedSchema().withInput("DEV")
                          .withOutput("MY_BOOK_WORLD"),
        new MappedSchema().withInput("LOG")
                          .withOutput("MY_BOOK_WORLD_LOG")));

使用上述映射配置的 Configuration 执行的查询实际上将生成此 SQL 语句:

SELECT *
FROM MY_BOOK_WORLD.AUTHOR
DSL.using(connection, dialect, settings)
   .selectFrom(DEV.AUTHOR)

这是有效的,因为 AUTHOR 是从 DEV 模式生成的,而 DEV 模式已通过上述设置映射到 MY_BOOK_WORLD 模式。

表映射

不仅模式可以映射,表也可以。如果您不是应用程序连接的数据库的所有者,您可能需要为每个表安装一个带有某种前缀的模式。在我们的示例中,这可能意味着您需要将 DEV.AUTHOR 映射到 MY_BOOK_WORLD.MY_APP__AUTHOR,其中 MY_APP__ 是应用于您所有表的缀。这可以通过创建以下映射来实现:

示例配置

Settings settings = new Settings()
    .withRenderMapping(new RenderMapping()
    .withSchemata(
        new MappedSchema().withInput("DEV")
                          .withTables(
         new MappedTable().withInput("AUTHOR")
                          .withOutput("MY_APP__AUTHOR"))));

使用上述映射配置的 Configuration 执行的查询实际上将生成此 SQL 语句:

SELECT * FROM DEV.MY_APP__AUTHOR

表映射和模式映射可以独立应用,方法是在上述配置中指定多个 MappedSchema 条目。jOOQ 将按出现顺序处理它们,并首次匹配时进行映射。请注意,您可以随时省略 MappedSchema 的输出值,在这种情况下,仅应用表映射。

UDT 映射

不仅模式可以映射,UDT 也可以。如果您不是应用程序连接的数据库的所有者,您可能需要为每个 UDT 安装一个带有某种前缀的模式。在我们的示例中,这可能意味着您需要将 DEV.AUTHOR_TYPE 映射到 MY_BOOK_WORLD.MY_APP__AUTHOR_TYPE,其中 MY_APP__ 是应用于您所有 UDT 的前缀。这可以通过创建以下映射来实现:

示例配置

Settings settings = new Settings()
    .withRenderMapping(new RenderMapping()
    .withSchemata(
        new MappedSchema().withInput("DEV")
                          .withUdts(
         new MappedUDT().withInput("AUTHOR_TYPE")
                          .withOutput("MY_APP__AUTHOR_TYPE"))));

使用上述映射配置的 Configuration 执行的查询实际上将生成此 SQL 语句:

SELECT CAST(ROW('John', 'Doe') AS DEV.MY_APP__AUTHOR_TYPE)

UDT 映射和模式映射可以独立应用,方法是在上述配置中指定多个 MappedSchema 条目。jOOQ 将按出现顺序处理它们,并首次匹配时进行映射。请注意,您可以随时省略 MappedSchema 的输出值,在这种情况下,仅应用 UDT 映射。

目录映射

对于 SQL Server 等数据库,除了模式之外,还可以映射目录。机制完全相同。因此,我们假设我们为表 [dev].[dbo].[author] 生成了代码,并希望在运行时将其映射到 [my_book_world].[dbo].[author]。可以通过以下方式实现:

示例配置

Settings settings = new Settings()
    .withRenderMapping(new RenderMapping()
    .withCatalogs(
        new MappedCatalog().withInput("DEV")
                           .withOutput("MY_BOOK_WORLD")));

为了让您完全控制每个表的映射方式,MappedCatalog 对象可以包含 MappedSchema(以及 MappedTable)定义。

使用正则表达式

以上所有示例都使用了 1:1 常量名称映射,其中输入和输出模式或表名称由配置固定。使用 jOOQ 3.8,也可以使用正则表达式进行映射,例如:

示例配置

Settings settings = new Settings()
    .withRenderMapping(new RenderMapping()
    .withSchemata(
        new MappedSchema().withInputExpression(Pattern.compile("DEV_(.*)"))
                          .withOutput("PROD_$1")
                          .withTables(
         new MappedTable().withInputExpression(Pattern.compile("DEV_(.*)"))
                          .withOutput("PROD_$1"))));

与常量版本唯一的区别是,在那种情况下,input 字段被替换为类型为 java.util.regex.PatterninputExpression 字段,而 output 字段的含义是模式替换,而不是常量替换。

在代码生成时硬编码映射

请注意,本手册关于 代码生成模式映射 的部分解释了如何在代码生成时硬编码您的目录、模式和表映射。

限制

映射的对象需要被 jOOQ org.jooq.RenderContext 了解,这意味着例如 纯 SQL 模板 及其内容无法被映射。有关更多详细信息,请参阅 需要代码生成的特性

反馈

您对本页面有任何反馈吗? 我们很乐意倾听!

The jOOQ Logo