@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 的经验,它成功地将 Map
s 绑定到 hstore
并将数组绑定到 postgreSQL array
s,因为这就是 PostgreSQL 的 jdbc 驱动程序所做的。
如果你想以特定的方式处理特定类型的对象,你可以实现 ArgumentFactory
s(似乎没有文档,但在 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()
方法)。
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 的经验,它成功地将 Map
s 绑定到 hstore
并将数组绑定到 postgreSQL array
s,因为这就是 PostgreSQL 的 jdbc 驱动程序所做的。
如果你想以特定的方式处理特定类型的对象,你可以实现 ArgumentFactory
s(似乎没有文档,但在 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()
方法)。