java - 在 Firebird 中通过 Jooq 使用 UUID PK 或 FK

标签 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。您的配置错误

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

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

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

2。您不能将类型重写两次

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

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

默认情况下,jOOQ 会读/写 CHAR使用 java.lang.String 类型和JDBC对应的PreparedStatement.setString()ResultSet.getString()方法,无论任何编码/排序规则/等。这可能不是您想要的。相反,您不应该实现 Converter但是一个Binding如此处记录的: https://www.jooq.org/doc/latest/manual/sql-building/queryparts/custom-bindings

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

关于java - 在 Firebird 中通过 Jooq 使用 UUID PK 或 FK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47313967/

相关文章:

java - 无论我做什么,Eclipse SVN 总是包含自动生成的 bin 目录和类

java - jOOQ - 重用 SelectConditionStep

java - JOOQ 强制类型将 POSTGRES 的 BigInteger 转换为 BigDecimal

java - 是否需要java的finalize方法?

java - 新部署给出嵌套异常是 java.lang.NoClassDefFoundError : org/postgresql/core/types/PGLong

java - Spring ACL 是一个好的 ACL 实现吗?

database-connection - Firebird 2.5 C++ 客户端 : error with DATE data type

超过Firebird交易计数

sql - 为什么我的 WHERE 子句会影响我的 LEFT JOIN?

java - 从连接查询中读取嵌套对象的最佳方法是什么