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