简体   繁体   English

JDBI在ResultSetMapper中获取参数类

[英]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 . 角色包含在另一个名为rolesroles 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM