使用SQL Object参数绑定时,JDBI是否可以与UUID参数一起使用?
我有一个这样的方法:
@SqlQuery("EXECUTE [MyProcedure] :myField")
MyDto myMethod(@Bind("myField") UUID myField);
绑定到接收如下参数的SQL Server存储过程:
@myField uniqueidentifier
执行时,抛出此异常:
! com.microsoft.sqlserver.jdbc.SQLServerException: The conversion from UNKNOWN to UNKNOWN is unsupported.
! at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:190)
! at com.microsoft.sqlserver.jdbc.DataTypes.throwConversionError(DataTypes.java:1117)
! at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setObject(SQLServerPreparedStatement.java:991)
如果我将JDBI上的参数类型更改为String,并使用UUID对象中的toString()方法调用它,它可以工作:
@SqlQuery("EXECUTE [MyProcedure] :myField")
MyDto trash(@Bind("myField") String myField);
有没有办法编写我的DAO方法接受UUID参数并在绑定之前将它们转换为字符串?
答案 0 :(得分:16)
JDBI仅为JDBC公开它们的类型公开基于显式类型的绑定。 JDBC不公开用于绑定的UUID类型,因此默认将其设置为Object。不幸的是,JDBC没有提供明确的UUID绑定机制,因此通过String可能是最便携的方式: - (
如果要在Java中将其绑定为UUID并在内部将其转换为String,则有两个路径。第一个,如果始终想要将UUID绑定为字符串,则使用ArgumentFactory,请参阅https://github.com/brianm/jdbi/blob/master/src/test/java/org/skife/jdbi/v2/sqlobject/TestRegisterArgumentFactory.java以获取示例。
第二种是,如果您只想在特定情况下执行此操作,请创建自定义活页夹,例如使用http://jdbi.org/sql_object_api_argument_binding/
使用ArgumentFactory实现从UUID到字符串的全局绑定的示例:
UUIDArgumentFactory.java:
public class UUIDArgumentFactory implements ArgumentFactory<UUID> {
@Override
public boolean accepts(Class<?> expectedType, Object value, StatementContext ctx) {
return value instanceof UUID;
}
@Override
public Argument build(Class<?> expectedType, UUID value, StatementContext ctx) {
return new UUIDArgument(value);
}
}
UUIDArgument.java:
public class UUIDArgument implements Argument {
private final UUID value;
public UUIDArgument(UUID value) {
this.value = value;
}
@Override
public void apply(int position, PreparedStatement statement, StatementContext ctx) throws SQLException {
statement.setString(position, value.toString());
}
}
寄存器:
final DatabaseFactory factory = new DatabaseFactory(environment);
final Database db = factory.build(configuration.getDatabaseConfiguration(), "sqlserver");
db.registerArgumentFactory(new UUIDArgumentFactory());