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

Can @Bind be used with enums and other arbitrary types using 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()

按照source code是用Enum.name(),不是toString()

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

如果你想以特定的方式处理特定类型的对象,你可以实现 ArgumentFactorys(似乎没有文档,但在 Stack Overflow) or BinderFactorys 中有一个例子(这是我现在才发现的。)

要解决您的 "arbitrary types" 问题,您可以实现 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() 方法)。