简体   繁体   English

jOOQ 使用一个数据库生成代码,另一个数据库执行它

[英]jOOQ using one database for generating code and another for executing it

We are changing databases, from one that supports an 8 bit int to one that does not.我们正在更改数据库,从支持 8 位 int 的数据库更改为不支持的数据库。 Our code breaks when Liquibase creates a DB that causes jOOQ to generate "short" variables but our code uses byte/Byte - this breaks code signatures.当 Liquibase 创建一个导致 jOOQ 生成“短”变量的数据库时,我们的代码会中断,但我们的代码使用字节/字节 - 这会破坏代码签名。

Rather than recode, somebody suggested that we continue to use the previous database (HSQLDB) to generate the code and it "should" run with the new database.有人建议我们继续使用以前的数据库(HSQLDB)来生成代码,而不是重新编码,它“应该”与新数据库一起运行。 There are dissenting opinions, I cannot find anything definitive beyond intuition and it seems to be counter to what jOOQ was designed for.有不同意见,除了直觉我找不到任何明确的东西,这似乎与 jOOQ 的设计目的背道而驰。 Has anyone done this successfully?有没有人成功地做到了这一点?

There is obviously no absolute yes/no answer to such a question, but there are several solutions/workarounds:对于这样的问题,显然没有绝对是/否的答案,但有几种解决方案/变通方法:

Use the previous database product to generate code使用之前的数据库产品生成代码

This will work for a short period of time, eg right now, but as you move on, it will be an extremely limiting factor for your schema design.这将在短时间内起作用,例如现在,但随着您继续前进,它将成为您的架构设计的一个极其限制因素。 You will continue tailoring your DDL and some other design decisions around what HSQLDB can do, and you won't be able to leverage other features of your new database product.您将继续围绕 HSQLDB 的功能调整 DDL 和其他一些设计决策,并且您将无法利用新数据库产品的其他功能。 This can be especially limiting when migrating data, as ALTER TABLE statements are quite different between dialects.这在迁移数据时尤其具有限制性,因为方言之间的ALTER TABLE语句完全不同。

I would recommend this approach only for a very short period of time, eg if you can't thoroughly fix this right away.我只会在很短的时间内推荐这种方法,例如,如果您不能立即彻底解决这个问题。

Use jOOQ's <forcedType/> mechanism to rewrite your data types使用 jOOQ 的<forcedType/>机制来重写你的数据类型

jOOQ's code generator allows for rewriting data types prior to loading the meta data of your schema into the code generator. jOOQ 的代码生成器允许在将架构的元数据加载到代码生成器之前重写数据类型。 This way, you can pretend your byte types are TINYINT on your new database product, even if your new database product doesn't support TINYINT .通过这种方式,你可以假装你的byte类型TINYINT你的新的数据库产品,即使您的新的数据库产品不支持TINYINT

This is a thorough solution that you may want to implement regardless of what product you're using, as it will give you a way to re-define parts of your schema just for jOOQ's code generator, independently of how you're generating your code.这是一个彻底的解决方案,无论您使用什么产品,您都可能想要实现它,因为它为您提供了一种方法,可以为 jOOQ 的代码生成器重新定义部分架构,而与生成代码的方式无关.

The feature is documented here: https://www.jooq.org/doc/latest/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-forced-types该功能记录在此处: https : //www.jooq.org/doc/latest/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-forced-types

This is definitely a more long term solution for your case.对于您的情况,这绝对是一个更长期的解决方案。

Notice, a future jOOQ will be able to use CHECK constraints as input meta data to decide whether to apply such a <forcedType/> .请注意,未来的 jOOQ 将能够使用CHECK约束作为输入元数据来决定是否应用这样的<forcedType/> I would imagine that you will place a CHECK (my_smallint BETWEEN -128 AND 127) constraint on every such column, so you could easily recognise which columns to apply the <forcedType/> to: https://github.com/jOOQ/jOOQ/issues/8843我想你会在每个这样的列上放置一个CHECK (my_smallint BETWEEN -128 AND 127)约束,这样你就可以轻松识别哪些列将<forcedType/>到: https : //github.com/jOOQ/jOOQ /问题/8843

Until that feature is available, you can implement it yourself via programmatic code generator configuration: https://www.jooq.org/doc/latest/manual/code-generation/codegen-programmatic/在该功能可用之前,您可以通过编程代码生成器配置自行实现: https : //www.jooq.org/doc/latest/manual/code-generation/codegen-programmatic/

Or, starting with jOOQ 3.12, by using a SQL expression to produce the regular expression that <forcedType/> matches.或者,从 jOOQ 3.12 开始,通过使用 SQL 表达式生成<forcedType/>匹配的正则表达式。 Eg in Oracle:例如在 Oracle 中:

<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>

You could use a file based meta data source您可以使用基于文件的元数据源

jOOQ doesn't have to connect to a live database instance to reverse engineer your schema. jOOQ 不必连接到实时数据库实例来对您的架构进行逆向工程。 You can also pass DDL code to jOOQ, or XML files:您还可以将 DDL 代码传递给 jOOQ 或 XML 文件:

This is not really solving your problem directly, but maybe, it might make solving it a bit easier.这并不是真正直接解决您的问题,但也许,它可能会使解决它更容易一些。 However, there are other limitations to these approaches, eg stored procedures aren't currently (jOOQ 3.12) supported, so I'm just adding this for completeness' sake here, not to suggest you use it right now.但是,这些方法还有其他限制,例如当前不支持存储过程(jOOQ 3.12),所以我只是为了完整起见在这里添加它,而不是建议您现在使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM