我在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)
答案 0 :(得分:2)
这里有几点需要解释:
在您当前的配置中,只有此部分适用于代码生成器,使用data type rewriting功能将您的CHAR
数据类型重写为VARBINARY
:
<forcedTypes>
<forcedType>
<name>VARBINARY</name>
<expressions>ID|ID_.*</expressions>
</forcedType>
</forcedTypes>
永远不会应用UUID
类型的自定义类型,因为您不会强制任何列为UUID类型。 (顺便说一下,您不应该为自定义类型UUID
命名,因为它与SQLDataType.UUID
冲突了)
当前版本的jOOQ 3.10不允许您重写两次类型,即从CHAR
到VARBINARY
,然后从VARBINARY
重写为您的用户定义类型。这是一个可能在未来版本中修复的限制。
但是现在,你必须一次性实现这一点。
默认情况下,jOOQ使用CHAR
和JDBC的java.lang.String
和PreparedStatement.setString()
方法读/写ResultSet.getString()
类型,无论编码/整理/是什么/这可能不是你想要的。相反,您不应该实现Converter
而是Binding
,如下所示:
https://www.jooq.org/doc/latest/manual/sql-building/queryparts/custom-bindings
它允许你&#34;绑定&#34;您的自定义数据类型直接发送到JDBC,绕过了jOOQ的内部DefaultBinding
语义(可以调用setString()
和getString()
)