@Bind可以使用JDBI与枚举和其他任意类型一起使用吗?

时间:2015-04-29 19:33:31

标签: java mysql dropwizard jdbi

JDBI是否支持通过注释绑定枚举类型?

例如,假设DAO包含一个方法:

@SqlQuery("select count(*) from answer a where a.foo = :foo")
Long someSqlQuery(@Bind("foo") Foo foo);

并且foo等于Foo.BAR,我可以期待查询:

select count(*) from answer a where a.foo = 'BAR'

如果是,是否toString()用于确定替换内容?

此外,JDBI是否允许@Bind使用任何扩展Object的类型?再次,如果是,是toString()使用了吗?

2 个答案:

答案 0 :(得分:10)

根据使用的source code Enum.name(),而不是toString()

如果绑定了一个对象,jdbi将使用您正在使用的jdbc驱动程序的setObject(Object object)。以我对PostgreSQL的经验为例,它成功地将Map绑定到hstore,将数组绑定到postgreSQL array,因为这是PostgreSQL的jdbc驱动程序所做的。

如果你想以特定的方式处理特定类型的对象,你可以实现ArgumentFactory s(似乎没有文档,但Stack Overflow中的示例)或{{ 3}}(我刚才发现的。)

答案 1 :(得分:1)

解决您的"任意类型"问题是,您可以实现BinderFactory绑定到您想要的任何内容。

@BindingAnnotation(UserBinder.UserBinderFactory.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface UserBinder {
    public static class UserBinderFactory implements BinderFactory {

        @Override
        public Binder build(Annotation annotation) {
            return new Binder<UserBinder, User>() {
                @Override
                public void bind(SQLStatement<?> q, UserBinder bind, User arg) {
                    q.bind("userId", arg.getUserId());
                    q.bind("uuid", arg.getUuid());
                    q.bind("openId", arg.getOpenId());
                    q.bind("givenName", arg.getGivenName());
                    // etc.
                }
            };
        }
    }
}

如果您希望以特定方式存储复杂类型,则此选项非常有用,例如:要转换为CSV或仅存储在单独的映射表中的二进制数据或集合。然后你就像这样使用新的花式活页夹:

@SqlUpdate(
        "INSERT INTO user (openId,givenName,uuid," +
        // etc.
        ") VALUES (:openId,:givenName,:uuid" +
        // etc.
        ")"
)
public abstract int createUser(
        @UserBinder User user
);

您还可以使用@BindBean注释,它将通过绑定参数名称自动查找对象上的字段(例如,它可以将查询占位符":userId"映射到getUserId()方法)。