ForceType检查约束或默认值

时间:2019-03-25 16:00:03

标签: java sql jooq

我在数据库中有如下列:

AKTIV VARCHAR2(1 char) default 'J' not null
    constraint AVCON_428946_AKTIV_000 check (AKTIV IN ('J', 'N')),

我必须如何编写ForcedType才能生成布尔字段。

到目前为止,我有:

<forcedType>
    <userType>java.lang.Boolean</userType>
    <converter>db.Varchar2ToBooleanConverter</converter>
    <types>VARCHAR2\(1\)</types>
    <nullability>NOT_NULL</nullability>
</forcedType>

但是如何包含默认值或检查约束?

1 个答案:

答案 0 :(得分:1)

这是一个非常有趣的用例,jOOQ当前无法立即使用,但您可以滚动自己的实现。一些背景

什么是检查约束

检查约束是可以放置在架构中以验证数据的谓词。虽然在很多情况下,您只会在单个列上应用这样的约束,但是您必须重复列名AKTIV的事实暗示着这样一个事实,即检查约束的作用域实际上是表,而不是表列。例如,您可能有约束条件

CONSTRAINT chk CHECK (col1 > 0 AND col2 IN (1, 2))

此约束不能明确地归因于单个列。但是像所有约束一样,它可以清楚地归因于表格。

domains是在PostgreSQL和SQL标准中定义检查约束的一种特殊方式,通常在多个表中用作可重用的检查约束。 jOOQ当前不适用于域。一些功能要求包括:

如何在jOOQ 3.11中以编程方式匹配它们

jOOQ-meta已经公开了CheckConstraintDefinition中的org.jooq.meta.Database.getCheckConstraints(SchemaDefinition)类型。如果您编写了programmatic code generator configuration,则可以阅读检查约束定义并以编程方式创建自己的forcedType配置相应地。 (可能)尚未在所有SQL方言中都可用。

另一种选择是直接查询数据库的字典视图,找到您感兴趣的检查约束,然后基于这些约束创建forcedType配置。例如,在Oracle中,您可以编写:

SELECT regexp_replace(search_condition_vc, '(\w+).*', '\1')
FROM all_constraints
WHERE constraint_name LIKE 'AVCON%' -- Add further restrictions here
AND regexp_like(search_condition_vc, 'IN\s*\(\s*''J''\s*,\s*''N''\s*\)')

现在可以从投影的SEARCH_CONDITION中使用正则表达式再次提取受影响的列名称。显然,您可能需要使以上逻辑适应您对域的了解。

如何在jOOQ 3.12中以配置方式匹配它们

我刚刚在jOOQ 3.12中实现了#8446,使用它也可以配置性地实现上述编程方法。您的<forcedType>如下所示:

<forcedType>
  <userType>java.lang.Boolean</userType>
  <converter>db.Varchar2ToBooleanConverter</converter>

  <!-- Place your SQL statement here -->
  <sql>
    SELECT regexp_replace(search_condition_vc, '(\w+).*', '\1')
    FROM all_constraints
    WHERE constraint_name LIKE 'AVCON%' -- Add further restrictions here
    AND regexp_like(search_condition_vc, 'IN\s*\(\s*''J''\s*,\s*''N''\s*\)')
  </sql>

  <!-- These may not be strictly needed -->
  <types>VARCHAR2\(1\)</types>
  <nullability>NOT_NULL</nullability>
</forcedType>