[英]JDBI getting argument class in ResultSetMapper
I am using Dropwizard with JDBI. 我正在将Dropwizard与JDBI一起使用。 I have a typical dao for user data:
我有一个典型的用户数据岛:
public interface UserDao
{
@SqlQuery("select * from users where role = :id")
@Mapper(UserMapper.class)
String findNameById(@BindBean Role role);
}
The user itself has an attribute with a Role
type: 用户本身具有
Role
类型的属性:
class User
{
private Role role;
/* the rest: other attributes, getters, setters, etc. */
}
Role is contained in another table called roles
. 角色包含在另一个名为
roles
表roles
。 Now, I need to map Role
in the mapper, but I do not want to change the SELECT ...
statement to add the JOIN roles ...
part. 现在,我需要在映射器中映射
Role
,但是我不想更改SELECT ...
语句以添加JOIN roles ...
部分。 We all know how joins affect queries and in the long run I'd like to avoid any joins if possible. 我们都知道联接如何影响查询,从长远来看,我希望尽可能避免任何联接。
I know, that ResultSetMapper
interface has a map()
method, which gets a StatementContext
passed to it. 我知道,
ResultSetMapper
接口具有map()
方法,该方法将一个StatementContext
传递给它。 That context has a getBinding()
method, which returns a Binding
class with all the data I need: 该上下文具有
getBinding()
方法,该方法返回具有我需要的所有数据的Binding
类:
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"
But that class com.example.Role
is not an instance of Role
, it's an instance of Argument
and I can't work with it. 但是
class com.example.Role
不是Role
的实例,它是Argument
的实例,我无法使用它。
So, is there a way to get that Role
argument and I just don't see it or do I have to instantiate it (again...) from the binding arguments (obviously they are there as debugger shows)? 因此,有没有一种方法可以获取该
Role
参数,而我只是看不到它,还是必须从绑定参数中实例化(再次...)(显然,如调试器所示,它们在那里)?
I finally solved it by using a custom binder. 我终于通过使用自定义绑定程序解决了它。 First, I modified
UserDao
to use @BindRole
instead of @BindBean
. 首先,我修改
UserDao
使用@BindRole
而不是@BindBean
。
Next, I had to create the binder for the role. 接下来,我必须为该角色创建活页夹。 Here the role is bound manually on separate values:
在这里,角色被手动绑定到单独的值上:
@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);
}
};
}
}
}
Notice the define()
method, it is responsible for setting attributes in StatementContext
, so don't overlook it. 注意
define()
方法,它负责在StatementContext
设置属性,因此请不要忽略它。
Next, in the mapper I just have to get the Role
with getArgument()
: 接下来,在映射器中,我只需要使用
getArgument()
来获取Role
:
Role role = new Role();
role.setId(1);
role.setName("TestRole");
Role r = (Role) statementContext.getAttribute("role");
boolean equals = e.equals(role);
In the debugger equals
is shown as true
, so problem solved. 在调试器中
equals
显示为true
,因此问题得以解决。 Woohoo. 哇噢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.