| Concept ACE | |
Ce document décrit l’utilisation des resolver de valeurs dans les ViewLink du fichier de configuration. Cette fonctionnalité vous permet de rendre le fichier de configuration complètement dynamique.
Auparavant, il existait trois types de paramètres dans les ViewLink du fichier de configuration :
Il arrivait donc parfois que l’on se retrouve dans l’obligation d’écrire des valeurs « en dur » alors que ces valeurs peuvent provenir du paramétrage. C’est souvent le cas dans certaines requêtes qui contiennent des sous-requêtes permettant de récupérer la valeur d’un type de tiers par exemple. Cela a comme effet principal d’alourdir considérablement les requêtes et le nom de paramètre public que l’on passe sur les URL.
Depuis la version ACE 1.3, il vous est possible de rendre le fichier de configuration complètement dynamique avec comme avantages principaux :
Le socle technique d’ACE (technicalframework) propose cette nouveauté fonctionnelle aux couches supérieures (métier et application). Le pilotage est réalisé dans les ViewLink, XDME est lui aussi impacté par cette nouveauté.
Afin de répondre à une utilisation la plus large et la plus souple possible, il a été décidé d’appliquer un principe équivalent aux resolver de requêtes, à savoir :
Dans le cas présent, nous parlerons de « resolver de valeurs » ou de « fournisseurs de valeurs ».
L’implémentation réalisée ce jour permet de résoudre principalement 3 types de valeurs :
Le nouvel attribut est nommé « solverName » car il s’agit d’un nom logique (non directement la référence à la classe Java).
Une sous-section de la section « application » permet de définir de manière globale les solver de tout type que l’on va exploiter dans la configuration. C’est une manière de généraliser leur exploitation avec un seul écran dans XDME.
Description des différents attributs :
Dans XDME, cette section est définie sous la forme d’un onglet général :
L’implémentation au niveau de socle se fait principalement dans les classes gérant les ViewLink, ainsi que dans le package :
Dans la couche métier, les différents solver livrés en standard se trouvent dans le package suivant :
Une liste de clients comporte deux paramètres obligatoires sur la table principale (table TIE) :
On a donc une requête définie dans la configuration qui, en plus de prendre ces champs là en compte, va comporter des paramètres optionnels (entourés de crochets : []).
La requête ressemble à ceci :
MevTie.CODSOC = ? AND TYPTIE = ? [ AND SIGTIE LIKE ?] [ AND NOMTIE LIKE ?] …
Dans XDME, le passage de paramètres ressemble à ceci :
Vue XML de cette partie de la configuration :
Toutes les valeurs à exprimer doivent être saisies en majuscule, il s’agit d’un choix de développement.
Les espaces de nommage d’ores et déjà disponibles sont les suivants :
Exemples de valeurs opérationnelles :
Liste des valeurs publiées pour les PPE (le nom est séparé par un « . ») :
Liste des valeurs (équivalent aux noms de champs) publiées pour le paramétrage de la fonction (PEV) :
|
|
Attention Les valeurs spécifiées sont sensibles à la casse, « PPE:TYPMAG.A1 » n'est pas équivalent à « ppe:typmag.A1 » par exemple. La casse doit donc être respectée. |
Il peut être intéressant dans certains cas de fournir la possibilité de réaliser directement des calculs sur les valeurs. A titre d’exemple, on peut noter que la clé d’un texte libre (table TXT) est une concaténation de plusieurs champs avec remplissage par des « 0 ».
Certaines fonctions sont donc implémentées pour répondre à ce besoin. Par la suite, de nouvelles fonctions pourront être développées au besoin par ACE Editeur.
Extensions des espaces de nommage :
Lorsque qu’aucune valeur de champ n’est demandée pour un PPE donné, le fournisseur de valeur renvoie TRUE ou FALSE. Par exemple, si le PPE TYPFOU est positionné, la syntaxe suivante renverra TRUE :
La valeur renvoyée est en majuscule, la casse ici aussi est fondamentale.
Les resolver classes permettent de résoudre les clauses Where définies dans le fichier de configuration. Il en existe plusieurs types à utiliser à bon escient. On distingue principalement :
Les resolver sont invoqués dynamique par le socle technique (technicalframework), mais sont implémentés sur la couche métier. Il est donc possible de créer ses propres resolver classes spécifiques en fonction des besoins.
Le but des resolver étant de passer dynamiquement des paramètres aux requêtes, ils n’existent que pour les ViewObject (à fortiori pas pour les APIs).
Il existe 2 moyens de remplacer une inconnue par un paramètre avec les resolver :
Le plus simple est de prendre un exemple avec une requête simple qui attend 2 paramètres obligatoires :
Select Codpro,Nompro,Typpro,Design1 from Pro where codsoc= ? and codpro= ?
Les paramètres (1 type numérique et 1 type caractère) prendront les valeurs suivantes :
En utilisant un resolver qui remplace les paramètres littéralement, on obtient la requête suivante :
Select Codpro,Nompro,Typpro,Design1 from Pro where codsoc=1113 and codpro=’TX106’
En utilisant un resolver qui bind les paramètres, la requête reste la même et on va passer les paramètres à Oracle pour qu’il réalise le travail lui-même.
select Codpro,Nompro,Typpro,Design1 from Pro where codsoc= ? and codpro= ?
Bind #1 è 1113
Bind #2 è TX106
Alors pourquoi ne pas utiliser un resolver qui bind les paramètres systématiquement ? Simplement parce qu’on ne peut pas dans ce cas passer un opérateur en paramètre (LIKE, >= …). Par exemple, on ne pourrait pas résoudre les requêtes auxquelles on passe des bornes de dates avec des opérateurs. La requête suivante serait insoluble :
select Codpro,Nompro,Typpro,Design1 from Pro where codsoc= ? and codpro= ‘?’ and Datcre ? ‘ ?’ and Datcre ? ‘ ?’
|
|
Attention Dans ce cas, les paramètres de type “VARCHAR2” doivent être entourés de quotes sinon la requête sera syntaxiquement erronée. |
Dans tous les cas, il est préférable d’exploiter les resolver bindant les paramètres, ceci pour 2 raisons :
Par contre dans le cadre de recherches multicritères, il est préférables d’utiliser les classes qui remplacent les paramètres littéralement afin d’obliger Oracle à parser la requête et trouver le chemin d’exécution optimum (explain plan).
Il arrive parfois qu’Oracle ne parvienne pas à trouver le meilleur plan d’exécution en particulier lorsque la requête met en jeu des tables partitionnées. Dans ce cas, le moteur de parsing travaille différemment (dans un cas, il dispose des valeurs dans les prédicats, dans l’autre le binding n’est effectué que lors de l’exécution de la requête).
Pour rappel, le cheminement est le suivant lors de l’exécution d’une requête :
n fr.ACE.technicalframework.application.DefaultWhereClauseResolver
BC4J, pas de paramètres optionnels, pas de quotes entre ? èBIND
n fr.generix.metier.clauseWhere.BusinessWhereClauseResolver
BC4J, paramètres optionnels autorisés, quotes entre ? è LITTERAL
n fr.generix.metier.clauseWhere.BindWhereClauseResolver
BC4J, paramètres optionnels autorisés, pas de quotes entre ? è BIND
n fr.ACE.technicalframework.application.DefaultSQLQueryResolver
Dynamique, pas de paramètres optionnels, pas de quotes entre ? è BIND
n fr.generix.metier.clauseWhere.BusinessSQLQueryResolver
Dynamique, paramètres optionnels autorisés, quotes entre ? è LITTERAL
n fr.generix.metier.clauseWhere.BindSQLQueryResolver
Dynamique, paramètres optionnels autorisés, pas de quotes entre ? è BIND
Depuis la version ACE 1.3, deux nouveaux resolvers sont disponibles. Ils autorisent le remplacement littéral de paramètres ainsi que le binding. Deux caractères différents sont utilisés suivant que l’on souhaite remplacer littéralement (@) ou binder ( ?).
Ce sont des resolver métiers, les règles habituelles sont utilisées lors des remplacements littéraux (mettre des quotes si la variable est du type VARCHAR et ne pas en mettre si c’est une expression numérique).
n fr.generix.metier.clauseWhere.BindLitteralSQLQueryResolver
Dynamique, paramètres optionnels autorisés, @ pour le remplacement littéral et ? pour les bind
n fr.generix.metier.clauseWhere.BindLitteralWhereClauseResolver
BC4J, paramètres optionnels autorisés, @ pour le remplacement littéral et ? pour les bind
Ces resolvers sont à privilégier dans le cadre des requêtes avec paramètres optionnels, ceci pour plusieurs raisons :
Il existe une clause particulière qui permet de demander au socle de ne pas passer de requête : NullClause
Dans certains cas d’utilisation, on peut vouloir ne passer la requête que si tous les paramètres sont disponibles (cas de certaines recherches par exemple). Il suffit alors de définir une requête sans paramètres optionnels (entourés de crochets) et d’utiliser le ResolverClass suivant :
n fr.generix.metier.clauseWhere.BindLitteralNullClauseResolver
Ce resolver prend en compte les jockers @ et ? suivant que l’on souhaite remplacer littéralement ou binder les paramètres.