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,所以问题解决了。哇哦。