JDBI 在 ResultSetMapper 中获取参数 class
JDBI getting argument class in ResultSetMapper
我正在将 Dropwizard 与 JDBI 结合使用。我有一个典型的用户数据 dao:
public interface UserDao
{
@SqlQuery("select * from users where role = :id")
@Mapper(UserMapper.class)
String findNameById(@BindBean Role role);
}
用户本身有一个 Role
类型的属性:
class User
{
private Role role;
/* the rest: other attributes, getters, setters, etc. */
}
角色包含在另一个名为 roles
的 table 中。现在,我需要在映射器中映射 Role
,但我不想更改 SELECT ...
语句来添加 JOIN roles ...
部分。我们都知道联接如何影响查询,从长远来看 运行 我想尽可能避免任何联接。
我知道,ResultSetMapper
接口有一个 map()
方法,它得到一个 StatementContext
传递给它。该上下文有一个 getBinding()
方法,其中 returns 一个 Binding
class 包含我需要的所有数据:
named = {HashMap$Node@1230} size = 3
0 = {HashMap$Node@1234} "id" -> "1"
1 = {HashMap$Node@1235} "name" -> "TestRole"
2 = {HashMap$Node@1236} "class" -> "class com.example.Role"
但是 class com.example.Role
不是 Role
的实例,它是 Argument
的实例,我无法使用它。
所以,有没有办法获得 Role
参数,我只是没有看到它,或者我是否必须从绑定参数(显然它们在那里)实例化它(再次...)如调试器所示)?
终于用自定义活页夹解决了。首先,我将 UserDao
修改为使用 @BindRole
而不是 @BindBean
。
接下来,我必须为角色创建活页夹。这里的角色被手动绑定到单独的值上:
@BindingAnnotation(BindRole.RoleBinderFactory.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface BindRole
{
public static class RoleBinderFactory implements BinderFactory
{
public Binder build(Annotation annotation)
{
return new Binder<BindRole, User>()
{
public void bind(SQLStatement q, BindRole bind, Role role)
{
q.bind("id", role.getId());
q.bind("name", role.getName());
q.define("role", role);
}
};
}
}
}
注意define()
方法,它负责设置StatementContext
中的属性,所以不要忽略它。
接下来,在映射器中,我只需要使用 getArgument()
:
获取 Role
Role role = new Role();
role.setId(1);
role.setName("TestRole");
Role r = (Role) statementContext.getAttribute("role");
boolean equals = e.equals(role);
在调试器中equals
显示为true
,所以问题解决了。哇哦。
我正在将 Dropwizard 与 JDBI 结合使用。我有一个典型的用户数据 dao:
public interface UserDao
{
@SqlQuery("select * from users where role = :id")
@Mapper(UserMapper.class)
String findNameById(@BindBean Role role);
}
用户本身有一个 Role
类型的属性:
class User
{
private Role role;
/* the rest: other attributes, getters, setters, etc. */
}
角色包含在另一个名为 roles
的 table 中。现在,我需要在映射器中映射 Role
,但我不想更改 SELECT ...
语句来添加 JOIN roles ...
部分。我们都知道联接如何影响查询,从长远来看 运行 我想尽可能避免任何联接。
我知道,ResultSetMapper
接口有一个 map()
方法,它得到一个 StatementContext
传递给它。该上下文有一个 getBinding()
方法,其中 returns 一个 Binding
class 包含我需要的所有数据:
named = {HashMap$Node@1230} size = 3
0 = {HashMap$Node@1234} "id" -> "1"
1 = {HashMap$Node@1235} "name" -> "TestRole"
2 = {HashMap$Node@1236} "class" -> "class com.example.Role"
但是 class com.example.Role
不是 Role
的实例,它是 Argument
的实例,我无法使用它。
所以,有没有办法获得 Role
参数,我只是没有看到它,或者我是否必须从绑定参数(显然它们在那里)实例化它(再次...)如调试器所示)?
终于用自定义活页夹解决了。首先,我将 UserDao
修改为使用 @BindRole
而不是 @BindBean
。
接下来,我必须为角色创建活页夹。这里的角色被手动绑定到单独的值上:
@BindingAnnotation(BindRole.RoleBinderFactory.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface BindRole
{
public static class RoleBinderFactory implements BinderFactory
{
public Binder build(Annotation annotation)
{
return new Binder<BindRole, User>()
{
public void bind(SQLStatement q, BindRole bind, Role role)
{
q.bind("id", role.getId());
q.bind("name", role.getName());
q.define("role", role);
}
};
}
}
}
注意define()
方法,它负责设置StatementContext
中的属性,所以不要忽略它。
接下来,在映射器中,我只需要使用 getArgument()
:
Role
Role role = new Role();
role.setId(1);
role.setName("TestRole");
Role r = (Role) statementContext.getAttribute("role");
boolean equals = e.equals(role);
在调试器中equals
显示为true
,所以问题解决了。哇哦。