【问题标题】:jOOQ using one database for generating code and another for executing itjOOQ 使用一个数据库生成代码,另一个用于执行代码
【发布时间】:2019-11-09 22:27:16
【问题描述】:

我们正在更改数据库,从支持 8 位 int 的数据库更改为不支持的数据库。当 Liquibase 创建一个导致 jOOQ 生成“短”变量但我们的代码使用字节/字节的数据库时,我们的代码会中断 - 这会破坏代码签名。

有人建议我们继续使用以前的数据库 (HSQLDB) 来生成代码,而不是重新编码,并且它“应该”与新数据库一起运行。有不同意见,除了直觉,我找不到任何确定的东西,这似乎与 jOOQ 的设计目的背道而驰。有没有人成功做到这一点?

【问题讨论】:

    标签: java sql jooq


    【解决方案1】:

    对于这样的问题显然没有绝对是/否的答案,但有几种解决方案/解决方法:

    使用之前的数据库产品生成代码

    这将在短时间内起作用,例如现在,但随着您继续前进,它将成为您的架构设计的一个极其限制因素。您将继续围绕 HSQLDB 的功能定制您的 DDL 和其他一些设计决策,并且您将无法利用新数据库产品的其他功能。这在迁移数据时尤其受到限制,因为ALTER TABLE 语句在方言之间存在很大差异。

    我只会在很短的时间内推荐这种方法,例如如果你不能马上彻底解决这个问题。

    使用 jOOQ 的 <forcedType/> 机制重写你的数据类型

    jOOQ 的代码生成器允许在将架构的元数据加载到代码生成器之前重写数据类型。这样,即使您的新数据库产品不支持 TINYINT,您也可以在新数据库产品上假装您的 byte 类型为 TINYINT

    这是一个彻底的解决方案,无论您使用什么产品,您都可能希望实施它,因为它会为您提供一种方法来重新定义架构的一部分,仅用于 jOOQ 的代码生成器,而与您的行为方式无关生成您的代码。

    这里记录了该功能: https://www.jooq.org/doc/latest/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-forced-types

    对于您的情况,这绝对是一个更长期的解决方案。

    注意,未来的 jOOQ 将能够使用CHECK 约束作为输入元数据来决定是否应用这样的<forcedType/>。我想你会在每个这样的列上放置一个CHECK (my_smallint BETWEEN -128 AND 127) 约束,这样你就可以很容易地识别出将<forcedType/> 应用于哪些列:https://github.com/jOOQ/jOOQ/issues/8843

    在该功能可用之前,您可以通过编程代码生成器配置自己实现它: https://www.jooq.org/doc/latest/manual/code-generation/codegen-programmatic/

    或者,从 jOOQ 3.12 开始,使用 SQL 表达式生成 <forcedType/> 匹配的正则表达式。例如。在甲骨文中:

    <forcedType>
      <name>TINYINT</name>
      <sql>
        select listagg(owner || '.' || table_name || '.' 
          || regexp_replace(search_condition_vc, ' between.*', ''), '|')
        from user_constraints
        where constraint_type = 'C'
        and regexp_like(search_condition_vc, '.* between -128 and 127');
      </sql>
    </forcedType>
    

    您可以使用基于文件的元数据源

    jOOQ 不必连接到实时数据库实例来对您的架构进行逆向工程。您还可以将 DDL 代码传递给 jOOQ 或 XML 文件:

    这并不能真正直接解决您的问题,但也许,它可能会使解决它更容易一些。但是,这些方法还有其他限制,例如目前不支持存储过程(jOOQ 3.12),所以我只是为了完整起见在这里添加它,而不是建议你现在使用它。

    【讨论】:

    • 我花了一段时间才回到这里,我们确实使用了forcedType方法,并且还遇到了其他问题,例如在一个引擎上使用“max(boolean)”的能力,因为boolean是实际上是整数,但是在另一个引擎上失败了(因为它确实应该)。使用“max(boolean)”实际上是一个“有任何集合吗?”分组。
    • @user3481644:你可以改用DSL.boolOr()
    猜你喜欢
    • 1970-01-01
    • 2018-01-26
    • 2020-01-07
    • 1970-01-01
    • 2016-06-12
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 2020-06-10
    相关资源
    最近更新 更多