2017-05-08 69 views
0

我正在使用帶有JDBI的Dropwizard。我有用於用戶數據的典型DAO:JDBI在ResultSetMapper中獲取參數類

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。現在,我需要在映射器中映射Role,但我不想更改SELECT ...語句來添加JOIN roles ...部件。我們都知道連接如何影響查詢,並且從長遠來看,如果可能的話,我想避免任何連接。

我知道,那ResultSetMapper接口有一個map()方法,它傳遞給它一個StatementContext。這方面有一個getBinding()方法,它返回一個Binding類我需要的所有數據:

named = {[email protected]} size = 3 
    0 = {[email protected]} "id" -> "1" 
    1 = {[email protected]} "name" -> "TestRole" 
    2 = {[email protected]} "class" -> "class com.example.Role" 

但這class com.example.Role不是Role一個實例,它是Argument一個實例,我不能使用它。

那麼,有沒有辦法得到Role參數,我只是沒有看到它,或者我必須從綁定參數(顯然它們在那裏作爲調試器顯示)實例化它(再次...)?

+0

第一次與角色無關,然後添加一個獲取角色的方法來設置用戶的角色。順便說一句,如果你的聯合有性能問題,我認爲你有一個索引問題 –

+0

我不明白你想說什麼。在哪裏添加get方法? –

+0

我不明白如果你正在嘗試使用'Role'設置'User'的'List',或者只是一個String' –

回答

0

我終於通過使用自定義綁定器解決了它。首先,我修改了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設置屬性,所以不要忽視它。

接下來,在映射我只是要得到RolegetArgument()

Role role = new Role(); 
role.setId(1); 
role.setName("TestRole"); 

Role r = (Role) statementContext.getAttribute("role"); 
boolean equals = e.equals(role); 

在調試equals顯示爲true,這樣問題就解決了。哇噢。