📖 Guide · Architecture · ORM_CSHX2

Jointures multi-niveaux

Mécanisme complet de gestion des jointures SQL dans ORM_CSHX2. Ce guide couvre les 9 champs de la structure ST_ORM_JOINTURE, la déclaration dans le constructeur des classes métier, les jointures chaînées multi-niveaux qui permettent de traverser plusieurs niveaux de relations sans SQL manuel, et l'hydratation profonde automatique des objets liés.

Architecture ST_ORM_JOINTURE · 9 champs LEFT · INNER · RIGHT JOIN Chaînage · Hydratation
01

📋 La structure ST_ORM_JOINTURE

Toute jointure ORM est décrite par une instance de ST_ORM_JOINTURE stockée dans le tableau de classe ::m_TabJointures. Elle porte toute l'information nécessaire pour trois opérations distinctes : générer la clause JOIN…ON, construire les colonnes JNT0n dans le SELECT, et hydrater l'objet lié après exécution.

ST_ORM_JOINTURE est une Structure // 🔗 Côté GAUCHE du ON : nouvelle table ajoutée par le JOIN sLeftTable est une chaîne sLeftField est une chaîne // 🔗 Côté DROIT du ON : table déjà présente (FROM ou JOIN précédent) sRightTable est une chaîne sRightField est une chaîne // 🔧 Type, alias et critères additionnels sJoinType est une chaîne // "INNER", "LEFT", "RIGHT" sJoinAlias est une chaîne // Alias respecté tel quel dans le SQL sAdditionalCriteria est une chaîne // 📤 Mapping objet et projection SELECT sObjectName est une chaîne sQueryFields est une chaîne FIN

Détail des 9 membres

🔗Côté GAUCHE du ON — nouvelle table ajoutée par le JOIN
sLeftTablechaîne
Nom de la nouvelle table ajoutée par le JOIN (côté gauche du ON). Ex.JOIN Contact AS ContactUser ON ContactUser.Contact_Id = User.d_Contact_Id_User sLeftTable = "Contact"
sLeftFieldchaîne
Clé de jointure côté gauche. Ex.Pour le JOIN ci-dessus sLeftField = "Contact_Id"
🔗Côté DROIT du ON — table déjà présente dans la requête
sRightTablechaîne
Table déjà présente dans la requête (issue du FROM ou d'un JOIN précédent). Ex.JOIN Contact AS ContactUser ON ContactUser.Contact_Id = User.d_Contact_Id_User sRightTable = "User"
sRightFieldchaîne
Clé de jointure côté droit. Ex.Pour le JOIN ci-dessus sRightField = "d_Contact_Id_User"
🔧Type, alias et critères additionnels
sJoinTypechaîne
Type de jointure SQL. Valeurs"INNER" · "LEFT" · "RIGHT"
sJoinAliaschaîne
Alias SQL de la table jointe. Respecté tel quel dans le SQL généré (la casse est préservée). Permet de référencer la même table physique plusieurs fois dans la même requête (ex. créateur / modificateur).
sAdditionalCriteriachaîne · optionnel
Condition supplémentaire injectée dans le ON de la jointure. Vide si aucun critère additionnel. Ex.sAdditionalCriteria = "AND fam.ACTIF = 1"
📤Mapping objet et projection SELECT
sObjectNamechaîne
Nom du membre WLangage de la classe métier qui portera l'objet lié hydraté après le SELECT. Ex.sObjectName = "m_clFamille"
sQueryFieldschaîne
Liste des colonnes de la table droite à inclure dans le SELECT. Ex.sQueryFields = "NOM_FAMILLE,CODE_FAMILLE"
ℹ️ Pas de champ sCodeSQL préconstruit

Contrairement à une approche naïve, la structure ne contient pas de clause JOIN préconstruite. Le composant reconstitue la clause dynamiquement depuis les 7 premiers champs au moment de l'exécution, ce qui lui permet de gérer automatiquement la casse des identifiants selon le provider actif (MySQL · MariaDB · PostgreSQL).

02

🏗️ Déclaration dans le constructeur

Chaque classe métier déclare ses jointures dans son constructeur, en alimentant le tableau ::m_TabJointures. Ce tableau est partagé au niveau classe — il est construit une seule fois pour toutes les instances.

// Constructeur de cArticle — jointure simple articles → familles LOCAL stJoin est une ST_ORM_JOINTURE stJoin.sLeftTable = "articles" stJoin.sLeftField = "FK_FAMILLE" stJoin.sRightTable = "familles" stJoin.sRightField = "ID_FAMILLE" stJoin.sJoinType = "LEFT" stJoin.sJoinAlias = "fam" stJoin.sAdditionalCriteria = "AND fam.ACTIF = 1" stJoin.sObjectName = "m_clFamille" stJoin.sQueryFields = "NOM_FAMILLE,CODE_FAMILLE" TableauAjouteLigne(::m_TabJointures, stJoin)
03

🔗 Jointures chaînées — multi-niveaux

Pour traverser plusieurs niveaux de relations (articles → familles → rayons → départements), chaque JOIN supplémentaire référence l'alias du JOIN précédent dans sLeftTable.

Niveau 2 — familles → rayons

// sLeftTable = alias du niveau 1 ("fam"), pas "familles" stJoin.sLeftTable = "fam" stJoin.sLeftField = "FK_RAYON" stJoin.sRightTable = "rayons" stJoin.sRightField = "ID_RAYON" stJoin.sJoinType = "LEFT" stJoin.sJoinAlias = "ray" stJoin.sAdditionalCriteria = "" stJoin.sObjectName = "m_clRayon" stJoin.sQueryFields = "NOM_RAYON" TableauAjouteLigne(::m_TabJointures, stJoin)

Niveau 3 — rayons → départements

stJoin.sLeftTable = "ray" stJoin.sLeftField = "FK_DEP" stJoin.sRightTable = "departements" stJoin.sRightField = "ID_DEP" stJoin.sJoinType = "LEFT" stJoin.sJoinAlias = "dep" stJoin.sAdditionalCriteria = "" stJoin.sObjectName = "m_clDepartement" stJoin.sQueryFields = "NOM_DEPARTEMENT" TableauAjouteLigne(::m_TabJointures, stJoin)

SQL résultant

LEFT JOIN familles fam ON fam.ID_FAMILLE = articles.FK_FAMILLE AND fam.ACTIF = 1 LEFT JOIN rayons ray ON ray.ID_RAYON = fam.FK_RAYON LEFT JOIN departements dep ON dep.ID_DEP = ray.FK_DEP
⚠️ Ordre d'insertion dans ::m_TabJointures

Les jointures doivent être déclarées dans l'ordre de dépendance : parent avant enfant. fam avant ray qui référence fam.FK_RAYON. Un ordre incorrect produit une erreur SQL Unknown column 'fam.FK_RAYON' à l'exécution.

04

👯 Même table jointe deux fois

Deux jointures vers la même table physique (ex. utilisateurs pour le créateur et le modificateur d'un enregistrement) sont différenciées par leur sJoinAlias, leur sObjectName, et leur index dans ::m_TabJointures (qui détermine le numéro JNT0n).

// JOIN 1 — créateur stJoin.sLeftTable = "commandes" stJoin.sLeftField = "SQL_ID_USER" stJoin.sRightTable = "utilisateurs" stJoin.sRightField = "ID_USER" stJoin.sJoinType = "LEFT" stJoin.sJoinAlias = "usr_crea" stJoin.sObjectName = "m_clUtilisateurCréateur" TableauAjouteLigne(::m_TabJointures, stJoin) // → JNT01 // JOIN 2 — modificateur stJoin.sLeftTable = "commandes" stJoin.sLeftField = "SQL_ID_USER_UPDATE" stJoin.sRightTable = "utilisateurs" stJoin.sRightField = "ID_USER" stJoin.sJoinType = "LEFT" stJoin.sJoinAlias = "usr_modif" stJoin.sObjectName = "m_clUtilisateurModificateur" TableauAjouteLigne(::m_TabJointures, stJoin) // → JNT02
05

📤 Projection SELECT — sQueryFields

sQueryFields liste les colonnes de la table droite à inclure dans le SELECT. Ces colonnes sont préfixées par l'alias de la jointure et automatiquement aliasées sous la forme JNT0n_NOMCOLONNE dans la requête générée :

// sQueryFields = "NOM_FAMILLE,CODE_FAMILLE" -- SELECT produit : fam.NOM_FAMILLE AS JNT01NOM_FAMILLE, fam.CODE_FAMILLE AS JNT01CODE_FAMILLE

Le numéro dans JNT01 correspond à la position (base 1) de la jointure dans ::m_TabJointures. Le composant gère automatiquement la génération des alias et leur résolution lors de l'hydratation des objets liés.