2014-10-21 1 views
5

스프링 프레임 워크에서 REST 서비스 백엔드를 만들었으므로 프런트 엔드의 일부 요청에서 복잡한 필터를 처리 할 방법을 찾아야합니다.jirutka/rsql-parser 및 QueryDSL

저는 QueryDsl (v3.4.2) 프레임 워크를 사용하여 백엔드 전체에서 쿼리를 구성합니다.

필자는 FIQL 또는 RSQL 파서를 사용하는 것이 가장 좋은 방법이라고 생각하여 jirutka/rsql-parser을 백엔드 프로젝트에 통합하려고합니다.

저는 QueryDsl에 대해서도 매우 익숙합니다.

지금 내가 도움을 내 요청 그래서 여기 혼란 스러워요 :
누구 통합 jirutka/rsql 파서과 전 휴식 봄 프로젝트 QueryDsl을 했습니까?어떻게?

Jirutka/rsql 파서 문서는 말한다 :

노드 이렇게 분석 된 AST를 통과 (어쩌면 SQL 쿼리로 변환)하기 위해, 참관, 당신이 제공 RSQLVisitor 인터페이스를 구현할 수 있습니다 또는 NoArgRSQLVisitorAdapter를 단순화했습니다.

그리고 그것을 수행하는 방법에 대한 다음 예제가 있습니다

Node rootNode = new RSQLParser().parse("name==RSQL;version=ge=2.0"); 
rootNode.accept(yourShinyVisitor); 

잘, 아주 쉽게 보인다을?

public class RsqlParserVisitor extends NoArgRSQLVisitorAdapter<BooleanExpression> { 

인터페이스 날에 필요한 모든 메소드를 구현 :

그래서 나는 이런 내 방문자가 상자에 포장.

a)는 QueryDsl BooleanExpression을 생성하기 위해, 나는 알 필요가 :

@Override 
public BooleanExpression visit(AndNode arg0) { 
    // TODO Auto-generated method stub 

    String methodNameTmp = "AndNode"; 
    logger.debug(methodNameTmp + ". arg0: " + arg0); 
    logger.debug("operator: " + arg0.getOperator().name()); 
    for (Node node : arg0) { 
     logger.debug(methodNameTmpp + ". node: " + node); 
    } 

    return null; //DO SOMETHING TO CREATE A BooleanExpression; 
} 

@Override 
public BooleanExpression visit(EqualNode arg0) { 
    // TODO Auto-generated method stub 
    String methodNameTmp = "EqualNode"; 
    logger.debug(methodNameTmp + ". arg0: " + arg0); 

    logger.debug("operator: " + arg0.getOperator()); 
    for (String arg: arg0.getArguments()) { 
     logger.debug(methodNameTmp + ". arg: " + arg); 
    } 

    return null; //DO SOMETHING TO CREATE A BooleanExpression; 
} 

지금은 붙어 : 여기

나는 두 가지 예를 추가 수업 처리 중입니다. 예 :

QUser qUser = QUser.user; 
    BooleanExpression filter = qUser.firstName.eq("Bob"); 

또는

PathBuilder<User> user = new PathBuilder<User>(User.class, "user"); 
    BooleanExpression filter = user.getString("firstName").eq("Bob"); 

B) 내 코드를 테스트, 그것은 단지 public BooleanExpression visit(OrNode arg0) 방법, 다음, 아무것도 실행되지 않습니다. 바로 거기에서 멈 춥니 다.

그 순간 나는 많이 할 수 없습니다. BooleanExpression을 아직 만들 수 없습니다. 먼저 일부 ComparisonNode 메서드를 통과 한 다음 "or"또는 "and"부울 식과 조인해야합니다. 권리?

적어도 모든 노드를 통과 할 수 있다면 클래스를 전달할 수있는 방법을 찾을 수 있습니다. 걱정할 필요가 없습니다. 그러나 모든 노드를 가로 지르는 방법을 이해하지 못하고 그것을 할 수 없었습니다.

이 문제를 해결할 수있는 모든 포인터는 정말 감사하겠습니다.

+0

혹시 이것에 대한 완벽한 솔루션을 찾으셨습니까? 나는 그것에 대해 듣고 싶다. –

+0

나는 tweeking 내 자신의 ... 그리고 지금까지 그렇게 잘 : 그것은 작동합니다. 하지만 지금은 일을하지 않을 때마다 문제를 해결해야합니다. 나는 그것이 완벽하지 않다는 것을 안다. 구체적인 질문이 있으시면 기꺼이 도와 드리겠습니다. 나는 언젠가는 얼마 남지 않은 시간 (하하)을 발견하고 여기에 몇 가지 조언을 할 수는 있지만, 약속 할 수있는 것이 아무것도 없길 바란다. :) – elysch

답변

0

언제나 그렇듯이, 질문을 한 후에 큰 진전을 보았습니다.

모든 노드를 통과하는 방법을 찾고 QueryDsl PathBuilder<?> 개체를 방문자에게 전달하는 방법을 찾았습니다.

PathBuilder<?>은 QueryDsl로 만든 모든 QSomething 클래스의 부모 클래스입니다.

이제 BooleanExpression을 만드는 방법을 찾고 있습니다.

도움을 주시면 감사하겠습니다.

지금 내 서비스에서 다음이

:

@Override 
public Page<User> getUsers(Emisor pEmisor, int pPage, int pSize, Sort pSort, String pRSQLFilters) { 

    Pageable pageable = new PageRequest(pPage, pSize, pSort); 

    BooleanExpression filters = null; 

    Node queryTree; 
    try { 
     logger.debug("Parsing query: {}", pRSQLFilters); 
     queryTree = new RSQLParser().parse(pRSQLFilters); 

     RsqlParserVisitor<BooleanExpression, QUser> rsqlParserVisitor = new RsqlParserVisitor<BooleanExpression, QUser>(); 
     filters = queryTree.accept(rsqlParserVisitor, QUser.user); 

    } catch (TokenMgrError e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (RSQLParserException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 


    Page<User> lista = userRepository.findAll(filtros, pageable); 

    return lista; 

}  

그리고이 방문자에 :

public class RsqlParserVisitor<BooleanExpression, A> implements RSQLVisitor<BooleanExpression, EntityPathBase<?>> { 
... 
    @Override 
    public BooleanExpression visit(OrNode node, EntityPathBase<?> param) { 
     // TODO Auto-generated method stub 

     String nombreTmp = "OrNode"; 
     printLogicalNode(nombreTmp, node, param); 

     return null; 
    } 

    @Override 
    public BooleanExpression visit(EqualNode node, EntityPathBase<?> param) { 
     // TODO Auto-generated method stub 

     String nombreTmp = "EqualNode"; 
     printComparisonNode(nombreTmp, node, param); 

     return null; 
    } 

... 

    public void printLogicalNode(String pNombreNodo, LogicalNode pNode, 
      EntityPathBase<?> pParam) { 
     logger.debug(pNombreNodo + ". node: " + pNode + ". param: " + pParam); 

     logger.debug("operator: " + pNode.getOperator().name()); 

     for (Node subNode : pNode) { 
      logger.debug(pNombreNodo + ". subNode: " + subNode); 
      subNode.accept(this, pParam); <=========== this was the key to be able to traverse every node 
     } 
    } 

    public void printComparisonNode(String pNombreNodo, ComparisonNode pNode, 
      EntityPathBase<?> pParam) { 
     logger.debug(pNombreNodo + ". node: " + pNode + ". param: " + pParam); 

     logger.debug("Selector: " + pNode.getSelector()); 
     logger.debug("operator: " + pNode.getOperator()); 

     for (String argTmp : pNode.getArguments()) { 
      logger.debug(pNombreNodo + ". argTmp: " + argTmp); 
     } 

    } 

} 
+0

안녕하세요, rsql-parser v2.x.x와 querydsl-core v3.x.x를 결합한 간단한 오픈 소스 프로젝트가 있는데 아직 진행 중입니다. 필자는 rsql-parser v1.x.x와 querydsl을 결합하여 업무 경험에서 파생 시켰습니다. 이번에는 그것을 github에 드러내고 싶습니다. 여기에서 찾을 수 있습니다. https://github.com/vineey/rsql-querydsl 현재, 내가 참고로이 분기 https://github.com/vineey/rsql-querydsl/tree/feature/filter-api – vine

+0

일하고, 2015 년 10 월 또는 그 이전에이 도서관을 끝낼 계획입니다. – vine

+0

참고로, 오픈 소스 프로젝트 rsql-queryds의 첫 번째 프로덕션 릴리스를 1.0.0.RELEASE https://github.com/vineey/archelix-rsql/ – vine