首页 > 解决方案 > 使用 JOOQ 工具强制 PostgreSQL 类型转换

问题描述

有没有办法配置 JOOQ 工具以使用 PostgresSQL 数据库的“forcedTypes”标签将smallint转换为布尔值,而不提供 org.jooq.Converter 实现?

这是当前配置的样子:

<forcedTypes>
    <forcedType>
        <name>BOOLEAN</name>
        <types>smallint.*</types>
    </forcedType>
<forcedTypes>

正在使用 JOOQ v3.9.1。PostgreSQL v9.6.6。

不幸的是,在将信息存储到数据库中时收到了下一个异常:

Caused by: org.postgresql.util.PSQLException: ERROR: column "is_complete" is of type smallint but expression is of type boolean

还尝试使用 MySQL 数据库和类似的从 tinyint 到 Boolean 的转换工作正常,没有任何错误:

<forcedTypes>
    <forcedType>
        <name>BOOLEAN</name>
        <types>tinyint.*</types>
    </forcedType>
</forcedTypes>

标签: postgresqltype-conversionjooq

解决方案


不,这不像你所期望的那样工作(也不应该)。在 jOOQ 中,如果数据库支持,则BOOLEAN数据类型作为本地BOOLEAN类型绑定到 JDBC,例如 PostgreSQL。

如果数据库不支持该类型(例如 MySQL/Oracle),那么 jOOQ 将绑定//0数字值。但是您不能对原本支持类型的方言强制执行此行为。但是话又说回来,为什么不写那个转换器呢?这真的很简单。只需添加:1NULLBOOLEAN

<forcedTypes>
    <forcedType>
        <userType>java.lang.Boolean</userType>
        <converter>com.example.BooleanAsSmallintConverter</converter>
        <!-- A bit risky. Are all smallints really booleans in your database? -->
        <types>smallint.*</types>
    </forcedType>
<forcedTypes>

进而:

class BooleanAsSmallintConverter extends AbstractConverter<Short, Boolean> {
    public BooleanAsSmallintConverter() {
        super(Short.class, Boolean.class);
    }

    @Override
    public Boolean from(Short t) {
        return t == null ? null : t.shortValue() != (short) 0;
    }

    @Override
    public Short to(Boolean u) {
        return u == null ? null : u ? Short.valueOf((short) 1) : Short.valueOf((short) 0);
    }
}

推荐阅读