2017-05-08 14 views
0

JDBI와 함께 Dropwizard를 사용하고 있습니다.ResultSetMapper에서 JDBI 인수 클래스 받기

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라는 다른 테이블에 포함되어 나는 사용자 데이터의 일반적인 DAO있다. 이제 매퍼에 Role을 매핑해야하지만 SELECT ... 문을 변경하여 JOIN roles ... 부분을 추가하고 싶지 않습니다. 우리는 조인이 쿼리에 어떻게 영향을 주는지, 그리고 장기적으로 가능한 경우 조인을 피하고 싶습니다.

저는 인터페이스에 메서드가 있고, StatementContext이 전달된다는 것을 알고 있습니다. 그 상황은 내가 필요로하는 모든 데이터로 Binding 클래스를 반환하는 getBinding() 방법이 있습니다

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.RoleRole의 인스턴스가 아닌, 그것은 Argument의 인스턴스이고 나는 그것이 작동하지 않을 수 있습니다.

그래서, Role 인수를 얻는 방법이 있습니까? 그냥 볼 수 없거나 바인딩 인수 (다시 그들은 디버거가 보여줍니다)에서 다시 인스턴스화해야합니까?

+0

처음으로 역할을 수행하지 않은 다음 get role 메소드를 추가하여 사용자의 역할을 설정하십시오. 그건 그렇고, 당신의 관절에 성능상의 문제가 있다면 나는 인덱스 문제가 있다고 생각합니다. –

+0

당신이 말하는 것을 이해하지 못합니다. 어디서 get 메소드를 추가할까요? –

+0

'Role'이 설정된'User'의'List' 또는 하나의'String'을 얻으려는 시도가 없다면 얻을 수 없습니다 –

답변

0

마지막으로 맞춤 바인더를 사용하여 해결했습니다. 먼저 UserDao@BindBean 대신 @BindRole으로 수정했습니다.

다음으로 역할을 위해 바인더를 만들어야했습니다. 다음 역할은 별도의 값을 수동으로 바인딩 :

@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()과 함께 얻을 수 있습니다 true으로 표시됩니다 디버거 equals에서

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

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

를, 그래서 문제가 해결. 우후.