9

使用 SQL 对象参数绑定时,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);

有没有办法编写接受 UUID 参数的 DAO 方法并在绑定之前将它们转换为字符串?

4

1 回答 1

17

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为例。

第二种是,如果你只想在特定情况下这样做,创建一个自定义的Binder,比如用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());
于 2012-08-20T02:29:44.110 回答