2009-09-11 19 views
5

Ho quello che sono sicuro è un problema abbastanza comune, e non voglio re-inventare la ruota. Ho un modulo di ricerca in cui gli utenti possono specificare i criteri di ricerca e il tipo di ricerca (AND O Ext ..).Creazione dinamica WHERE clause from user Criteri di ricerca

Il modulo passa nuovamente id che mappano i nomi ei valori delle colonne. Attualmente sto usando Java lato server per incollare insieme le stringhe in una clausola where. Funziona in alcuni casi, ma è goffo, soggetto a errori e non si adatta bene.

Qualche suggerimento?

Grazie,

David

+2

Potresti approfondire il motivo per cui ritieni che questo sia goffo e soggetto a errori? Forse potresti pubblicare un codice di esempio che illustri questo. –

risposta

0

si deve costruire la stringa di ricerca sia sul client o sul server. Costruirlo sul client non è ovviamente una buona soluzione (per quanto riguarda la sicurezza), quindi l'unica opzione è quella di crearlo sul server. Personalmente, vorrei utilizzare o costruire un oggetto Searcher, che gestisce l'attività ricorrente di costruire stringhe di ricerca in modo efficiente e crea una dichiarazione da lì.

1

Se si stava utilizzando un ORM (utilizzo Hibernate), è possibile utilizzare l'API Criteri: consente di aggregare le condizioni (utilizzando un loop ad esempio) e crea la query risultante.

In SQL nativo, non so una libreria che avrebbe fatto. Forse potresti scrivere il tuo, trarre ispirazione dalla documentazione e dal codice per i Criteri di ibernazione?


O:

Se fate qualcosa di sufficientemente complesso sul client (ad esempio di gestire le priorità tra AND e OR, è possibile nidificare condizioni usando parentesi ...), allora probabilmente siete già costruendo una struttura dati che gestisce questo sul client.

In tal caso, vi consiglio di inviare quella struttura dati al server, e usarlo tramite loop per creare la query.

0

Hibernate ha un'API Criteria che permette di creare query dinamiche utilizzando metodo solo invocazione, senza necessità di composizione manuale della query SQL.

Ma si dovrebbe considerare l'utilizzo di una soluzione per la ricerca a testo integrale come Lucene o Hibernate Search, che riducono notevolmente la necessità di query con condizione complessa. La ricerca a testo integrale è anche una soluzione molto migliore per l'esperienza dell'utente, poiché una ricerca a testo integrale è più semplice da eseguire e di solito fornisce risultati migliori.

1

Vorrei usare preparare e? per i parametri comunque, se non altro per evitare l'iniezione e altri rischi di non conformità.

Se i criteri di ricerca sono di dimensioni limitate, è possibile elencare staticamente tutte le query possibili da preparare.

In caso contrario, è possibile mantenere un pool di query preparate in modo dinamico. Questo non è così utile per un'app web, dove probabilmente non riusciate a riutilizzare nessuna delle domande che preparate.

0

Il suggerimento di Massimiliano Fliri di guardare l'API dei criteri mi ha portato nella giusta direzione. Ho smesso di pensare di costruire "solo una clausola where" e ho iniziato a pensare a questo come alla necessità di compilare dichiarazioni.

Questo mi ha portato a una soluzione: Squiggle-sql: http://code.google.com/p/squiggle-sql/

Dalla documentazione:

Squiggle è una libreria Java po 'per la generazione in modo dinamico istruzioni SQL SELECT. È un buon punto per le applicazioni che hanno bisogno di creare query complicate con criteri che cambiano in fase di esecuzione. Normalmente può essere abbastanza doloroso capire come costruire questa stringa. Squiggle toglie gran parte di questo dolore.

+0

Nota: a prima vista, quella libreria non sembra supportare istruzioni e parametri preparati. Ad esempio, le stringhe sembrano incorporate direttamente nell'SQL generato dalla libreria. Ciò potrebbe portare a vulnerabilità di attacco di SQL injection. Potrei sbagliarmi... –

0

Se si utilizza l'ibernazione come ORM, utilizzare l'API Criteri per eseguire questa operazione. Deve essere più facile aggiungere/rimuovere clausole basate su alcune condizioni.

Se si sta creando una query JDBC tenere la parte che è costante prima e accodare la parte variabile per es

select * from trans dove userid =?

e aggiungere in base alle condizioni per es
se importo! = Null quindi aggiungere 'e la quantità>? '

Fintanto che è possibile mantenere la parte costante ben separata dalla parte variabile, non si dovrebbero avere molti problemi.

0

Il libro "Sviluppo SQL Server Expert 2005" di Adam Machanic contiene alcuni suggerimenti eccellenti nel capitolo 7 relativo all'SQL dinamico. Si tuffa in tutti i tipi di problemi tra cui prestazioni, manutenibilità e sicurezza. Non cercherò di riscrivere il suo capitolo - basti dire che crede che less is more quando si tratta di SQL.

È specifico per SQL Server, ma credo che il suo approccio generale (enorme dove clausola contro/se SQL vs dinamico) può essere applicato su tutta la linea.

EDIT: Penso che vale la pena di aggiungere ... non fidarsi mai di input da parte del cliente, parametrizzare sempre il vostro input prima di utilizzarlo in SQL.

Problemi correlati