【问题标题】:Does JDBI accept UUID parameters?JDBI 是否接受 UUID 参数?
【发布时间】:2012-08-18 21:39:29
【问题描述】:

使用 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);

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

【问题讨论】:

    标签: java jdbc jdbi


    【解决方案1】:

    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());
    

    【讨论】:

    • 解决了这个问题。我可以使用 UUID 定义 DAO API,并在它们绑定到参数时将它们转换为字符串。我将我的代码添加到答案中。
    • 请注意,接受用于绑定的 UUID 参数的能力不是 JDBI 的属性,而是数据库的底层 JDBC 驱动程序的属性。例如,我正在使用 Postgres,它具有本机 UUID 列类型,并且 Postgres JDBC 驱动程序使用 PreparedStatement.setObject() 接受 UUID。因此,UUID 的本机绑定无需 ArgumentFactory 即可工作。
    • 如果您想在全局范围内注册 ArgumentFactory,而不是必须注释每个受影响的类(如 TestRegisterArgumentFactory 中的示例),请在设置 DBI 句柄时调用 DBI.registerArgumentFactory()。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 2018-08-22
    相关资源
    最近更新 更多