2014-10-21 17 views
5

Ho il framework Spring creato il back-end dei servizi REST e ora ho bisogno di trovare un modo per elaborare filtri complessi in alcune richieste dal front-end.jirutka/rsql-parser e QueryDSL

Utilizzo il framework QueryDsl (v3.4.2) per eseguire la costruzione di query su tutto il back-end.

Penso che usare un parser FIQL o RSQL sia l'approccio migliore, quindi sto cercando di integrare jirutka/rsql-parser nel mio progetto di back-end.

Sono molto nuovo ad esso e anche a QueryDsl.

Ora sono confusa: ecco la mia richiesta di aiuto:
Qualcuno ha integrato jirutka/rsql-parser e QueryDsl in un progetto di riposo primavera prima? e Come?

Jirutka documentazione/rsql-parser dice soltanto:

I nodi sono visitabili, in modo da attraversare l'AST analizzato (e convertirlo in query SQL forse), è possibile implementare l'interfaccia RSQLVisitor fornito o NoArgRSQLVisitorAdapter semplificato.

E ha il seguente esempio su come farlo:

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

sembra abbastanza facile, giusto?

Così ho ingabbiati mio visitatore in questo modo:

public class RsqlParserVisitor extends NoArgRSQLVisitorAdapter<BooleanExpression> { 

Implementato tutti i metodi le interfacce necessarie me.

Qui aggiungo due esempi:

@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; 
} 

e

@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; 
} 

Ora mi sono bloccato:

a) Al fine di creare un QueryDsl espressione booleana, ho bisogno di sapere il classe che sto elaborando ad esempio:

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

o

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

b) quando verifico il mio codice, esegue solo il public BooleanExpression visit(OrNode arg0) metodo, poi più nulla. Si ferma proprio lì.

In quel momento non posso fare molto. Non è ancora possibile creare un'espressione booleana, poiché prima devo passare attraverso alcuni metodi ComparisonNode e quindi unirmi a un'espressione booleana "or" o "e". Destra?

Se almeno potessi passare attraverso tutti i nodi, allora potrei trovare un modo per superare la classe, non sono preoccupato. Ma non capisco come attraversare tutti i nodi, e non sono stato in grado di farlo.

Qualsiasi suggerimento per risolvere questo problema, sarà davvero apprezzato.

+0

Hai mai trovare una soluzione completa per questo? Mi piacerebbe saperlo. –

+0

Ho finito per twittare il mio ... e finora tutto bene: funziona. Ma ogni tanto ho bisogno di aggiustare le cose quando non funziona; So che non è perfetto. Sarei lieto di aiutarti se hai domande specifiche. Spero presto di trovare un po 'di tempo libero (ha ha) e di mettere qui alcuni suggerimenti, ma non posso promettere nulla. :) – elysch

risposta

0

Come sempre, dopo aver fatto la domanda ha fatto grandi progressi (credo).

Trovato un modo per attraversare tutti i nodi e trovato un modo per passare l'oggetto QueryDsl PathBuilder<?> al visitatore.

PathBuilder<?> è la classe padre di tutte le classi QSomething create da QueryDsl.

Ora sono bloccato di nuovo cercando un modo per creare l'espressione booleana.

Qualsiasi aiuto sarebbe molto apprezzato.

Ora ho il seguente al mio servizio:

@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; 

}  

E questo nel visitatore:

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

Ciao, ho un semplice progetto open-source che combina rsql-parser v2.x.x e querydsl-core v3.x.x, è ancora in corso. L'ho derivato dalla mia esperienza lavorativa combinando rsql-parser v1.x.x e querydsl. Questa volta voglio esporlo in github, puoi trovarlo qui. https://github.com/vineey/rsql-querydsl Attualmente, sto lavorando su questo ramo https://github.com/vineey/rsql-querydsl/tree/feature/filter-api – vine

+0

FYI, Sto pianificando di terminare questa libreria entro o prima di ottobre 2015. – vine

+0

Cordiali saluti, sono lieto di annunciare la prima versione di produzione del mio progetto opensource rsql-queryds tagged come 1.0.0.RELEASE https://github.com/vineey/archelix-rsql/ – vine

Problemi correlati