9

SQLオブジェクトの引数バインディングを使用する場合、JDBIはUUIDパラメーターですぐに機能しますか?

私はこのような方法を持っています:

@SqlQuery("EXECUTE [MyProcedure] :myField")
MyDto myMethod(@Bind("myField") UUID myField);

これは、次のようなパラメーターを受け取るSQLServerストアドプロシージャにバインドされています。

@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タイプを公開しないため、デフォルトでオブジェクトとして設定されます。残念ながら、JDBCは明示的なUUIDバインディングメカニズムを提供していないため、Stringを使用するのがおそらく最も移植性の高い方法です:-(

JavaでUUIDとしてバインドし、内部で文字列に変換する場合は、2つのパスがあります。まず、文字列としてUUIDを常にバインドする場合は、ArgumentFactoryを使用します。https://github.com/brianm/jdbi/blob/master/src/test/java/org/skife/jdbi/v2/sqlobjectを参照してください。例については、 /TestRegisterArgumentFactory.javaを参照してください。

2つ目は、特定の場合にのみ実行する場合は、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 に答える