使用Jooq在Firebird中使用UUID PK或FK

时间:2017-11-15 17:39:49

标签: java firebird jooq firebird-3.0

我在Firebird中有一个带有PK列的表

CREATE TABLE TEST
(
  ID CHAR(16) CHARACTER SET OCTETS NOT NULL,
  CONSTRAINT PK_TEST PRIMARY KEY (ID)
);

OCTETS编码被视为字节。

我创建了一个转换器

public class UUIDConverter implements Converter<byte[], UUID>{

    @Override
    public Class<byte[]> fromType() {
        return byte[].class;
    }

    @Override
    public Class<UUID> toType() {
        return UUID.class;
    }

    @Override
    public UUID from(byte[] bytes) {
        if (bytes == null) return null;
        ByteBuffer bb = ByteBuffer.wrap(bytes);
        long high = bb.getLong();
        long low = bb.getLong();
        return new UUID(high, low);
    }

    @Override
    public byte[] to(UUID uuid) {
        if (uuid == null) return null;
        byte[] buffer = new byte[16];
        ByteBuffer bb = ByteBuffer.wrap(buffer);
        bb.putLong(uuid.getMostSignificantBits());
        bb.putLong(uuid.getLeastSignificantBits());
        return buffer;
    }
}

然后我将转换器配置在我的pom中(我使用maven来生成源代码)

<customTypes>
    <customType>
        <name>UUID</name>
        <converter>com.vas.database.UUIDConverter</converter>
    </customType>
</customTypes>
<forcedTypes>
    <forcedType>
        <name>VARBINARY</name>
        <expressions>ID|ID_.*</expressions>
    </forcedType>
</forcedTypes>

虽然生成了代码,但它并不是我所期望的。

public final TableField<TestRecord, byte[]> ID = createField("ID", org.jooq.impl.SQLDataType.VARBINARY.nullable(false), this, "");

这就是我希望它生成的内容(我手工完成了更改,一切都运行得非常好。)

public final TableField<TestRecord, UUID> ID = createField("ID", org.jooq.impl.SQLDataType.VARBINARY.nullable(false), this, "", new UUIDConverter());

如何让它发挥作用? (顺便说一句,我使用Firebird 3.0,Jooq 3.10.1和Jaybird 2.2.13)

1 个答案:

答案 0 :(得分:2)

这里有几点需要解释:

1。您的配置错误

在您当前的配置中,只有此部分适用于代码生成器,使用data type rewriting功能将您的CHAR数据类型重写为VARBINARY

<forcedTypes>
    <forcedType>
        <name>VARBINARY</name>
        <expressions>ID|ID_.*</expressions>
    </forcedType>
</forcedTypes>

永远不会应用UUID类型的自定义类型,因为您不会强制任何列为UUID类型。 (顺便说一下,您不应该为自定义类型UUID命名,因为它与SQLDataType.UUID冲突了)

2。你不能重写两次类型

当前版本的jOOQ 3.10不允许您重写两次类型,即从CHARVARBINARY,然后从VARBINARY重写为您的用户定义类型。这是一个可能在未来版本中修复的限制。

但是现在,你必须一次性实现这一点。

默认情况下,jOOQ使用CHAR和JDBC的java.lang.StringPreparedStatement.setString()方法读/写ResultSet.getString()类型,无论编码/整理/是什么/这可能不是你想要的。相反,您不应该实现Converter而是Binding,如下所示: https://www.jooq.org/doc/latest/manual/sql-building/queryparts/custom-bindings

它允许你&#34;绑定&#34;您的自定义数据类型直接发送到JDBC,绕过了jOOQ的内部DefaultBinding语义(可以调用setString()getString()