Domanda

Abbiamo bisogno di produrre un abbastanza complesso generatore di query dinamica per recuperare i rapporti al volo. Stiamo graffiando le nostre teste un po 'che tipo di struttura di dati sarebbe meglio.

E 'davvero niente di più che in possesso di un elenco di selectParts, un elenco di fromParts, una lista di dove criteri, order by, raggruppare, quel genere di cose, per la persistenza. Quando si comincia a pensare si unisce, in particolare outer join, avendo clausole, e funzioni di aggregazione, le cose cominciano a diventare un po 'confuso.

Stiamo costruendo in su interfacce prima per ora e cercare di pensare il più avanti possibile, ma sicuramente passerà attraverso una serie di refactoring quando scopriamo le limitazioni con le nostre strutture.

sto postando questa domanda qui nella speranza che qualcuno ha già messo a punto qualcosa che possiamo basare su. O sa di qualche libreria o qualcosa del genere. Sarebbe bello avere alcuni consigli o heads-up su potenziali problemi prima che ci tuffiamo in implementazioni prossima settimana.

È stato utile?

Soluzione

Ho fatto qualcosa di simile paio di volte in passato. Un paio di cose più grandi in mente ..

  • La clausola WHERE è la più difficile da ottenere. Se si divide le cose in quello che chiamerei "espressioni" e "predicati" rende più facile.
  • Espressioni - riferimenti di colonna, parametri, letterali, funzioni, aggregati (conteggio / sum)
  • predicati - confronti, come, tra, in, è nullo (predicati hanno espressione come i bambini, per esempio expr1 = espr2 Poi avendo anche materiali compositi quali e / o / no
  • ..
  • L'intera clausola where, come potete immaginare, è un albero con un predicato alla radice, con forse sotto-predicati sotto eventualmente il blocco con le espressioni le foglie.
  • Per costruire il HQL si cammina il modello (di profondità prima di solito). Ho usato un visitatore come ho bisogno di camminare i miei modelli per altri motivi, ma se non si dispone di più fini si può costruire il codice di rendering a destra nel modello.

es. Se tu avessi

"where upper(column1) = :param1 AND ( column2 is null OR column3 between :param2 and param3)"

Poi l'albero è

Root
- AND
  - Equal
    - Function(upper)
      - ColumnReference(column1)
    - Parameter(param1)
  - OR
    - IsNull
      - ColumnReference(column2)
    - Between
      - ColumnReference(column3)
      - Parameter(param2)
      - Parameter(param3)

Poi si cammina la profondità dell'albero prima e unire pezzi resi di HQL sulla via del ritorno in su. La funzione superiore per esempio ci si aspetta un pezzo di bambino HQL da rendere e sarebbe quindi generare

"upper( " + childHql + " )"

e passare che fino al suo genitore. Qualcosa di simile si aspetta Tra Bambino tre pezzi HQL.

  • È quindi possibile riutilizzare il modello di espressione nel select / gruppo da / clausole ORDER BY

  • È possibile saltare la memorizzazione del gruppo da parte, se lo si desidera, semplicemente memorizzare la scansione di costruzione query di selezione e prima per l'aggregato. Se c'è una o più quindi solo copiare tutte le espressioni di selezione non di aggregazione nel gruppo da.

  • Da clausola è solo un elenco di tabella di riferimento + zero o più clausole di unirsi. Ogni aderire clausola ha un tipo (destra interna / sinistra /) e un riferimento tavolo. Tabella di riferimento è il nome della tabella + alias opzionale.

Inoltre, se mai a desiderare di analizzare un linguaggio di interrogazione (o qualcosa di veramente), allora posso raccomandare ANTLR . La curva di apprendimento è piuttosto ripida, ma ci sono un sacco di esempio grammatiche da guardare.

HTH.

Altri suggerimenti

se avete bisogno di EJB QL-parser e strutture dati, EclipseLink (beh molti di esso è classi interne) hanno buona:

JPQLParseTree tree = org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.buildParserFor(" _the_ejb_ql_string_ ").parse();

JPQLParseTree contiene i tutti i dati.

, ma la generazione di EJB QL-ritorno da JPQLParseTree modificato è qualcosa che dovete fare da soli.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top