使用JOOQ工具强制进行PostgreSQL类型转换

时间:2018-06-21 07:59:38

标签: postgresql type-conversion jooq

是否有一种方法可以将JOOQ工具配置为使用PostgresSQL数据库的'forcedTypes'标签将 smallint 转换为 Boolean ,而无需提供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>

2 个答案:

答案 0 :(得分:1)

不,这不符合您的预期(并且不应该)。在jOOQ中,如果数据库支持,BOOLEAN数据类型将作为本地BOOLEAN类型绑定到JDBC。 PostgreSQL。

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

<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);
    }
}

答案 1 :(得分:0)

您可以这样做,但是我怀疑这就是您的想法。您将必须在PostgreSQL中创建custom cast

CREATE FUNCTION bool2int2(IN bool, OUT int2)
LANGUAGE SQL
AS $$
SELECT CASE WHEN $1 THEN 1::int2 WHEN $1 IS NOT NULL THEN 0::int2 END
$$;

DROP CAST IF EXISTS (bool AS int2);
CREATE CAST (bool AS int2)
WITH FUNCTION bool2int2(bool)
AS ASSIGNMENT;

然后这将起作用:

DROP TABLE IF EXISTS booltest;
CREATE TABLE booltest (id serial, boolval int2);
INSERT INTO booltest (boolval) VALUES(true),(false),(null::bool);
SELECT * FROM booltest;
 id | boolval
----+---------
  1 |       1
  2 |       0
  3 | (null);