2

我在 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)

4

1 回答 1

2

这里有几件事要解释:

1.你的配置错误

在您当前的配置中,只有这部分适用于代码生成器,将您的数据类型重写CHARVARBINARY使用数据类型重写功能:

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

永远不会应用该UUID类型的自定义类型,因为您不会将任何列强制为 UUID 类型。(顺便说一句,您不应该命名您的自定义类型UUID,因为这与SQLDataType.UUID

2. 一个类型不能重写两次

当前版本的 jOOQ 3.10 不允许您重写类型两次,即 from CHARtoVARBINARY和 from VARBINARYto 您的用户定义类型。这是一个限制,可能会在未来的版本中修复。

但是现在,您必须一口气实施。

默认情况下,jOOQ 将使用和 JDBC 对应的和方法读取/写入CHAR类型,而不管任何编码/排序规则/等。这可能不是您想要的。相反,您不应该实现 a但 a如此处所述: https ://www.jooq.org/doc/latest/manual/sql-building/queryparts/custom-bindingsjava.lang.StringPreparedStatement.setString()ResultSet.getString()ConverterBinding

它允许您将自定义数据类型直接“绑定”到 JDBC,绕过 jOOQ 的内部DefaultBinding语义(将调用setString()and getString()

于 2017-11-20T11:05:52.943 回答