使用 MSSQL 数据库类型别名,jooq 3.7.3 将它们转换为正确的 Java 类型,但 3.12.3 将它们全部转换为 Java 类型 Object

Posted

技术标签:

【中文标题】使用 MSSQL 数据库类型别名,jooq 3.7.3 将它们转换为正确的 Java 类型,但 3.12.3 将它们全部转换为 Java 类型 Object【英文标题】:Using MSSQL database types aliases, jooq 3.7.3 converted them to the proper Java type, but 3.12.3 converts them all to java type Object 【发布时间】:2020-03-09 18:30:10 【问题描述】:

例如,我有一个数据库类型别名定义如下:

create type aml_acct from varchar(50) not null

然后在创建表的 SQL 中,我会有这样的列定义:

create table ACCOUNTS (
  .   
  acct aml_acct,
  .
)

在 3.7.3 中,Jooq 生成的代码是这样的:

public final TableField<AmlAccountsRecord, String> ACCT = 
   createField("acct", org.jooq.impl.SQLDataType.VARCHAR.length(50).nullable(false), this, "");

在 3.12.3 中,Jooq 生成的代码是这样的:

    /**
     * @deprecated Unknown data type. Please define an explicit @link org.jooq.Binding to specify how this type should be handled. Deprecation can be turned off using @literal <deprecationOnUnknownTypes/> in your code generator configuration.
     */
    @java.lang.Deprecated
    public final TableField<AmlAccountsRecord, Object> ACCT = createField(DSL.name("acct"), org.jooq.impl.SQLDataType.OTHER.nullable(false), this, "");

但我不知道如何创建一个 Binding 类以使其正确处理 aml_acct 数据库类型并像以前一样生成代码。或者有没有办法通过ForcedType 处理这个问题?

任何想法或帮助将不胜感激......

【问题讨论】:

【参考方案1】:

jOOQ 中的一个错误

这是 jOOQ 3.12 代码生成器中的一个错误(可能也存在于以前的版本中)。 jOOQ 代码生成器的最新版本增加了对 SQL Server 中表值函数和表值参数的支持。为此,编写了新的SYSINFORMATION_SCHEMA 查询来获取元数据以用于SQL Server 的代码生成。在这种情况下,SYS.ALL_COLUMNSUSER_TYPE_ID 列而不是SYSTEM_TYPE_ID 列上连接到SYS.TYPES

这将在 3.13.0 和 3.12.4 中修复:https://github.com/jOOQ/jOOQ/issues/9551。

解决方法

解决方法是使用&lt;forcedType&gt; 配置将列的类型强制为所需的数据类型: https://www.jooq.org/doc/latest/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-forced-types/

例如:

<forcedType>
  <name>VARCHAR</name>
  <includeTypes>aml_acct</includeTypes>
</forcedType>

如果你有很多这样的类型,你也可以在上面的配置中使用&lt;sql&gt;来匹配所有应该应用这个强制类型的列。这可能如下所示:

<forcedType>
  <name>VARCHAR</name>
  <sql>
    select string_agg(o.name + '\.' + c.name, '|')
    from sys.all_objects o
    join sys.all_columns c on o.object_id = c.object_id
    join sys.types u on c.user_type_id = u.user_type_id
    join sys.types t on u.system_type_id = t.system_type_id
    where u.is_user_defined = 1
    and t.name = 'varchar'
  </sql>
</forcedType>

有关详细信息,请参阅上述文档链接。

【讨论】:

感谢您的快速回复!我会给出关于 ForcedTypes 的建议。

以上是关于使用 MSSQL 数据库类型别名,jooq 3.7.3 将它们转换为正确的 Java 类型,但 3.12.3 将它们全部转换为 Java 类型 Object的主要内容,如果未能解决你的问题,请参考以下文章

RETURNING 的别名导致 jooq

Jooq 与 SQL Server 如何选择前 N 个结果

jOOQ:如何查看已别名的字段?

jOOQ - 别名和引号错误

使用 JOOQ 从 MS SQL 数据库生成代码时遇到问题

使用别名访问MSSQL Express