J'ai travaillé sur une application de servlet Java qui a besoin de construire des instructions SQL très dynamiques à des fins de reporting ad hoc. La fonction de base de l'application est de nourrir un tas de paramètres de requête HTTP nommés dans une requête pré-codée et de générer un tableau de sortie bien formaté. J'ai utilisé Spring MVC et le framework d'injection de dépendances pour stocker toutes mes requêtes SQL dans des fichiers XML et les charger dans l'application de création de rapports, avec les informations de mise en forme du tableau. Finalement, les exigences en matière de rapports sont devenues plus compliquées que les capacités des cadres de mappage de paramètres existants et j'ai dû écrire les miennes. Ce fut un exercice de développement intéressant et a produit un cadre pour la cartographie des paramètres beaucoup plus robuste que tout ce que j'ai pu trouver.
Les nouveaux mappages de paramètres se présentaient comme tels:
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 beauté du cadre résultant était qu'il pouvait traiter les paramètres de requête HTTP directement dans la requête avec une vérification de type et une vérification de limite appropriées. Aucun mappage supplémentaire requis pour la validation d'entrée. Dans l'exemple de requête ci-dessus, le paramètre nommé serverId
serait vérifié pour s'assurer qu'il pouvait être converti en un entier et qu'il était compris entre 0 et 50. Le paramètre appId serait traité comme un tableau d'entiers, avec une limite de longueur de 50. Si le champ showOwnerest présent et mis à "true", les bits de SQL entre guillemets seront ajoutés à la requête générée pour les mappages de champs optionnels. field Plusieurs autres mappages de types de paramètres sont disponibles, y compris des segments facultatifs de SQL avec d'autres mappages de paramètres. Il permet un mappage de requête aussi complexe que le développeur peut le proposer. Il a même des contrôles dans la configuration du rapport pour déterminer si une requête donnée aura les mappages finaux via un PreparedStatement ou simplement exécutée en tant que requête pré-construite.
Pour les exemples de valeurs de requête Http:
showOwner: true
serverId: 20
appId: 1,2,3,5,7,11,13
Cela produirait le SQL suivant:
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
Je pense vraiment que Spring ou Hibernate ou l'un de ces frameworks devrait offrir un mécanisme de mappage plus robuste qui vérifie les types, permet des types de données complexes comme les tableaux et d'autres fonctionnalités similaires. J'ai écrit mon moteur uniquement pour mes besoins, il n'est pas tout à fait lu pour la version générale. Cela ne fonctionne qu'avec les requêtes Oracle pour le moment et tout le code appartient à une grande entreprise. Un jour, je pourrai prendre mes idées et créer un nouveau framework open source, mais j'espère que l'un des grands acteurs existants relèvera le défi.