Ho lavorato su un'applicazione servlet Java che ha bisogno di costruire istruzioni SQL molto dinamiche per scopi di reporting ad hoc. La funzione di base dell'app è alimentare un gruppo di parametri di richiesta HTTP denominati in una query precodificata e generare una tabella di output ben formattata. Ho usato Spring MVC e il framework di inserimento delle dipendenze per archiviare tutte le mie query SQL in file XML e caricarle nell'applicazione di reportistica, insieme alle informazioni sulla formattazione della tabella. Alla fine, i requisiti di reporting sono diventati più complicati delle capacità dei framework di mappatura dei parametri esistenti e ho dovuto scriverne uno mio. È stato un interessante esercizio di sviluppo e ha prodotto un framework per la mappatura dei parametri molto più robusto di qualsiasi altra cosa che ho potuto trovare.
Le nuove mappature dei parametri sembravano tali:
select app.name as "App",
${optional(" app.owner as "Owner", "):showOwner}
sv.name as "Server", sum(act.trans_ct) as "Trans"
from activity_records act, servers sv, applications app
where act.server_id = sv.id
and act.app_id = app.id
and sv.id = ${integer(0,50):serverId}
and app.id in ${integerList(50):appId}
group by app.name, ${optional(" app.owner, "):showOwner} sv.name
order by app.name, sv.name
La bellezza del framework risultante era che poteva elaborare i parametri della richiesta HTTP direttamente nella query con il controllo del tipo e il controllo dei limiti appropriati. Nessun mapping aggiuntivo richiesto per la convalida dell'input. Nella query di esempio precedente, il parametro denominato serverId
verrebbe controllato per assicurarsi che possa eseguire il cast su un numero intero e rientrare nell'intervallo 0-50. Il parametro appId verrebbe elaborato come un array di numeri interi, con un limite di lunghezza di 50. Se il campo showOwnerè presente e impostato su "true", i bit di SQL tra virgolette verranno aggiunti alla query generata per le mappature dei campi opzionali. campo Sono disponibili molte altre mappature del tipo di parametro, inclusi segmenti opzionali di SQL con ulteriori mappature dei parametri. Consente una mappatura delle query tanto complessa quanto lo sviluppatore può fornire. Ha anche controlli nella configurazione del report per determinare se una determinata query avrà le mappature finali tramite una PreparedStatement o semplicemente eseguita come query precostruita.
Per i valori di richiesta Http di esempio:
showOwner: true
serverId: 20
appId: 1,2,3,5,7,11,13
Produrrebbe il seguente SQL:
select app.name as "App",
app.owner as "Owner",
sv.name as "Server", sum(act.trans_ct) as "Trans"
from activity_records act, servers sv, applications app
where act.server_id = sv.id
and act.app_id = app.id
and sv.id = 20
and app.id in (1,2,3,5,7,11,13)
group by app.name, app.owner, sv.name
order by app.name, sv.name
Penso davvero che Spring o Hibernate o uno di questi framework dovrebbero offrire un meccanismo di mappatura più robusto che verifica i tipi, consente tipi di dati complessi come array e altre funzionalità simili. Ho scritto il mio motore solo per i miei scopi, non è abbastanza letto per il rilascio generale. Al momento funziona solo con le query Oracle e tutto il codice appartiene a una grande azienda. Un giorno potrei prendere le mie idee e costruire un nuovo framework open source, ma spero che uno dei grandi attori esistenti accetterà la sfida.