Acces BD
Acces BD
Acces BD
C++ Builder, comme Delphi ou Visual Basic, permet de créer facilement des
applications orientées "gestion", s'appuyant sur un système de gestion de base de données
relationnelles ( SGBDR ).
Page XII.1
Construction d'applications orientées données
Ici encore les mécanismes mis en œuvre par C++ Builder sont ceux créés pour
Delphi. Seules les différences de syntaxes existant entre le langage Pascal et le
langage C++ distinguent les deux environnements.
Ce mode sépare l'aspect physique des données ( stockage sur disque) de leur
représentation logique ( présentation à l'utilisateur ). Les données apparaissent alors à ce
dernier sous forme de tables qui masquent la complexité des mécanismes d'accès en mémoire.
Le modèle relationnel libère l'utilisateur de tous les détails de stockage et permet de concevoir
un accès purement logique aux données.
Chaque table permet de stocker un type particulier de données. Une donnée stockée
constitue un enregistrement dans la table (= une ligne). Elle peut être constituée d'un nombre
variable d'informations élémentaires. Chaque information élémentaire constitue un champ de
l'enregistrement (= une colonne).
Par exemple on peut définir le champ "Nom" comme index pour pouvoir
avoir une vision "triée" des enregistrements selon les différents noms
contenus dans la base. Mais "nom" ne peut être une clé car il peut y
avoir homonymie entre deux personnes .
Lorsqu'un index correspond à une clé on dit qu'il est "primaire". Dans les autres
cas il est dit "secondaire".
Toutes les données (enregistrements) d'une table sont définies par les mêmes
champs.
Page XII.2
Construction d'applications orientées données
Dans les faits, le gestionnaire de base de données met en place une zone mémoire
tampon dans lequel il recopie systématiquement l'enregistrement courant. Lorsque l'utilisateur
réalise des modifications, c'est sur cette copie qu'elles interviennent. Il n'y a que quand
l'utilisateur valide les modifications ( implicitement, lorsqu'il change d'enregistrement courant,
ou explicitement ) que la zone mémoire tampon est recopiée sur le disque et qu'elle écrase la
valeur de l'enregistrement courant.
Pour que cela soit possible il faut établir des liens entre les différentes tables de la base.
Ces liens permettent de retrouver des informations dans une table à partir d'une autre table.
On peut imaginer une base de données contenant une table contenant les
renseignements sur différents clients ( avec identification Nom / Prénom / Adresse /
etc. ) de chaque client ). On peut alors créer une autre table contenant les
informations sur les opérations réalisées par ce client ( Achat / Vente / Date de
l'opération / Prix / Etc. ). La table "Opérations" dépend de la table "Client" qui est la
table maîtresse de la base.
Les liens entre tables ne peuvent être réalisés qu'à l'aide de champs définis comme des
clés. Cela garantit que les informations lues dans une table sont bien celles correspondant à la
donnée de la table "maître".
Dans l'exemple précédent la clé de la table "Clients" ( clé interne ou clé externe )
est utilisée dans un des champ de la table "Opérations" pour que chaque
enregistrement de la table puisse être rattachée à un client bien précis.
Les requêtes :
Page XII.3
Construction d'applications orientées données
Dans le cas d'une base utilisée dans le contexte client / serveur, seule la requête est
transmise au serveur. Celui-ci la traite puis renvoie les résultats au client.
Une requête est formulée selon un langage particulier, qui est d'ailleurs un des
fondements des bases de données relationnelles : le langage SQL.
Les vues :
Les requêtes permettent de ne visualiser que les enregistrements ou les données qui
remplissent certains critères. Le gestionnaire de base de données est en mesure de
réaliser ces opérations et ne fournir à l'utilisateur que les "vues" qu'il souhaite des
différentes tables.
Une vue peut être affichée sous forme de tableau ( chaque ligne correspond à un
enregistrement et les colonnes correspondent aux champs sélectionnés ) ou sous
forme de fiche : un seul enregistrement est à l'écran en même temps.
Lorsqu'une table est triée selon un index secondaire, elle présente à l'utilisateur une
"vue" qui diffère de son implémentation physique. Normalement on ne peut
modifier les données affichées dans une vue. Mais C++Builder soutient le principe
des "requêtes vivantes" (requests live) qui permet de modifier les données affichées
sous forme de vues de manière à ce que ces modifications remontent jusqu'aux
tables d'où les données sont extraites.
Page XII.4
Construction d'applications orientées données
Le moteur de base de données BDE est l'élément central d'une application de gestion de
base de données créée avec C++ Builder.
Son accès est réalisé directement via des composants spécifiques fournis avec C++
Builder. Un programmeur n'a donc pas à s'occuper de la gestion de BDE et il n'apparaît
pas dans l'arborescence de l'application créée. Par contre l'exécutable généré est plus
important ( inclusion des différents mécanismes d'accès à BDE ).
Interface utilisateur
Report Smith
Application
ou QReport
C++ Builder Etats
Pilotes ODBC
Page XII.5
Construction d'applications orientées données
Cet utilitaire indépendant, accessible par une icône spécifique ou par le menu 'Outils',
permet de créer les différentes tables de l'application ( dénominations, types et tailles
des différents champs et définition des clés), de définir les différents index, de créer les
liens entre les différentes tables.
Il est possible d'utiliser et / ou modifier des tables déjà conçues par d'autres SGBDR
(Paradox ou dBase).
Les pilotes ODBC permettent l'accès à différentes bases de données et serveurs SQL
non reconnus directement par C++ Builder.
Dans le cadre de la conception d'une application, DBD doit être utilisé juste après la
réalisation du modèle conceptuel de données. Il permet de créer les tables qui découlent de ce
modèle.
L'utilitaire DBD est en fait une version "allégée" du SGBDR Paradox auquel
seules certaines fonctionnalités ont été ôtées ( création de l'interface utilisateur,
génération d'états ) car reprises par Delphi et Report Smith ou QReport. Les
utilisateurs de Paradox n'auront aucune difficulté à prendre en main DBD.
D'ailleurs pour aller au delà des informations fournies sur DBE par l'aide en
ligne ( nettement trop concise dans ce domaine) il est souhaitable de se munir
d'un livre d'apprentissage à Paradox.
Il faut donc créer un répertoire particulier par application créée. Ce répertoire est appelé
"répertoire de travail". Sa détermination ( définition du chemin absolu du répertoire de
travail ) permet à DBD, et ultérieurement à BDE, de gérer rapidement l'ensemble des
tables de l'application.
Un utilitaire spécial, accessible par une icône du groupe de programme C++ Builder,
permet de définir le "répertoire de travail" dans lequel DBD générera et stockera les
différents objets constituants une base.
Page XII.6
Construction d'applications orientées données
On peut aussi définir un "répertoire privé" dans lequel DBD stocke des tables
temporaires et éventuellement des tables générées en cas d'incident lors de vérification
d'intégrité.
La notion d'alias est une notion très souple. Elle permet de développer une application
complète en s'affranchissant de la configuration physique de la machine support. Il
suffit en effet de configurer l'alias ( grâce à l'utilitaire adéquat ) pour prendre en compte
un chemin d'accès aux différentes tables différent ( de celui utilisé lors de la phase de
conception mais aussi, éventuellement, en cas de déplacement de l'application sur
d'autres machines ).
Page XII.7
Construction d'applications orientées données
Page XII.8
Construction d'applications orientées données
La boite permet aussi, sur sa partie droite, de définir les champs qui devront être
obligatoirement être renseignés, les valeurs minimales et maximales, ainsi qu'un
masque de saisie éventuel.
La table est ensuite créée lorsque l'utilisateur lui donne un nom via "enregistrer
sous ...".
Par défaut, DBD crée cette table dans le répertoire de travail (mais il est possible de
spécifier un autre répertoire).
Si des clés, index, liens, etc. sont spécifiés, DBD crée de nombreux fichiers internes
contenant les informations de gestion correspondantes ( c'est pour cela qu'il faut bien
spécifier un répertoire de travail particulier pour chaque application).
Page XII.9
Construction d'applications orientées données
Le terme "index" a ici le sens de clé. Une clé peut être simple ( un
champ ) ou composée ( plusieurs champs forment la clé ).
Il existe toujours, en fin de liste, un champ "vide" numéroté. Ce champ n'est pas pris
en compte lors de la création effective de la table ( lors de l'enregistrement de son
nom ).
Propriétés de la table :
Ces différentes possibilités sont accessibles via une boite de dialogue déroulante
dénommée "Propriétés de la table". Par défaut, DBD propose les fonctionnalités
suivantes :
Il est possible de déterminer quels sont les champs devant être obligatoirement
renseignés par l'utilisateur lors de l'exécution de l'application. BDE ne validera
l'entrée des données que si ces champs sont remplis.
Page XII.10
Construction d'applications orientées données
'Défaut' permet de donner une valeur par défaut à un champ ( cette valeur sera
celle qui sera validée si l'utilisateur n'en entre pas une autre).
Ils permettent aussi de définir les caractères acceptés dans des champs
alphabétiques et permettent les entrées automatiques ( le fait d'entrer un caractère
ou une séquence donnée génère automatiquement le reste de la donnée ).
Il n'est pas vraiment utile de réaliser ces modèles car leur syntaxe
est assez déroutante et, surtout, elle est différente de celle utilisée
dans les éditeurs de masque de C++ Builder .
Autres propriétés :
Table de référence :
Une table de référence permet d'indiquer que les valeurs que l'on entre dans un
champ doivent déjà exister dans le premier champ d'une autre table ou de copier
des valeurs automatiquement à partir de la table de référence vers une table en
cours de modification ( remplissage automatique ).
Pour établir une liaison plus solide entre deux tables, on définit une
relation d'intégrité référentielle.
Index secondaire :
Un index secondaire est un champ ou un groupe de champs utilisé dans plusieurs
cas:
- Pour réaliser une table de correspondance des valeurs du champ spécifié ;
- Pour pouvoir effectuer un ordre de tri différent de celui imposé par la clé
primaire de la table.
Page XII.11
Construction d'applications orientées données
Intégrité référentielle :
L'intégrité référentielle est un mécanisme interne à BDE qui sert à assurer qu'une
valeur de champ entrée dans une table (dite "table enfant") existe déjà dans un
champ spécifié dans une autre table (dite " table parent").
Pour pouvoir définir une règle d'intégrité référentielle entre deux tables celles-ci
doivent comporter une clé primaire et se trouver dans le même répertoire.
Il faut prendre cependant en compte que, à partir du moment où une table est créée, il
est possible de l'ouvrir, sous forme d'un tableau, puis de l'éditer afin d'y entrer des
enregistrements.
Cette possibilité est intéressante pour générer facilement des jeux d'essai, lorsque l'on
crée une application, pour y réaliser des modifications et ..... pour tester la validité des
fonctions créées sous C++ Builder.
DBD peut toujours être invoqué à partir de C++ Builder, alors que le développement de
l'application est déjà entamé, pour préciser certains contrôles, pour créer de nouveaux
index qui s'avèrent nécessaires voire pour restructurer les tables.
Page XII.12
Construction d'applications orientées données
Pour ce faire il faut lancer un utilitaire spécifique qui n'est accessible qu'à partir de la
fenêtre de programme C++ Builder. Son icône est appelée 'Administrateur BDE'.
Cet utilitaire est assez complexe à utiliser car il permet le paramétrage "physique" de la
base de données et des différents liens existant entre les données stockées, BDE, et
l'application C++ Builder ( taille des buffers, types de transferts, format des dates et de
certains séparateurs, etc. ). Sans compétence de haut niveau il est préférable de ne pas modifier
les valeurs par défaut des paramètres de configuration.
Le seul paramètre qu'il est utile, voire impératif, de modifier est la définition de l'alias
de la base de données.
Un alias est, on l'a vu, très utile pour réaliser facilement des applications C++ Builder
importantes. Cependant cela oblige à utiliser les pilotes IDAPI, livrés avec l'environnement
dans des disquettes de distribution ( stockées sur CD ROM ).
De fait l'utilisation des alias impose un surcoût d'environ 1 Mo sur disque ainsi
qu'une procédure d'installation spécifique de l'application.
Page XII.13
Construction d'applications orientées données
Lorsque l'administrateur BDE est lancé il faut, pour créer un alias, cliquer sur le bouton
droit de la souris pour faire apparaître une petite boite de dialogue permettant de définir le type
de base de données ( dbase ou Paradox mais aussi tous les formats susceptibles d'être
reconnus par l'application en utilisant des pilotes ODBC ou autres ).
Une fois ce premier choix réalisé, un nouveau item apparaît dans l'arborescence de la
boite de dialogue ( avec un nom du type STANDARD1 ). Il faut alors :
- Renommer cet item. Ce nom sera l'alias de la base de données.
- Indiquer, dans la zone de saisie précédée par le mot PATH le chemin d'accès au
répertoire privé de la base ( encore une fois chaque base doit être stockée dans un
répertoire qui lui est propre ). Via le bouton située à droite de la zone de saisie il est
possible de parcourir l'arborescence des disques locaux ou distants.
Pour des applications peu importantes il est préférable d'indiquer "en dur" les chemins
d'accès aux différentes tables. C'est plus contraignant, au niveau de la programmation, lors de
la réalisation de l'application mais cela permet de créer des applications plus légères et plus
faciles à installer.
On verra plus loin qu'il est possible de créer, par programmation, un alias.
Il faut néanmoins respecter certaines règles et utiliser toutes ou parties des disquettes de
distribution stockées dans un répertoire particulier du CD ROM de C++ Builder (les disquettes
contiennent des modules permettant d'installer tout ou partie de BDE, Report Smith et SQL
Links).
Déployer une application C++ Builder signifie la confier à l'utilisateur final et lui
fournir tous les éléments lui permettant de l'installer et de l'utiliser dans son environnement de
travail en accord avec la législation en vigueur.
Une application C++ Builder peut ainsi exiger l'installation de toute ou partie de :
- Le fichier .EXE de l'application (et toutes les DLL spéciales éventuellement).
- Borland Database Engine (BDE), si l'application est une application de bases de
données.
- Le cas échéant le support de SQL Links, d'InterBase SQL Link, d'InterBase Local,
si l'application utilise InterBase Local ou le support du runtime de ReportSmith.
Page XII.14
Construction d'applications orientées données
La licence d'utilisation d'une application C++ Builder exige que tous les fichiers du
BDE redistribuable soient installés avec l'utilitaire d'installation. L'application peut ne pas avoir
besoin de tous ces fichiers ( certains sont des pilotes spécifiques à chaque langue nationale ), et
l'on peut ensuite supprimer les fichiers inutiles afin de préserver l'espace disque. Mais si tous
les fichiers nécessaires ne sont pas conservés, les applications existantes risquent de ne pas
fonctionner.
Page XII.15
Construction d'applications orientées données
TDBNavigator
TDBGrid
BDE
BDE
TTable TDataSource TDBEdit
Données
TDBCheck
Fiche Delphi
Liens entre les différents composants proposés par C++ Builder : il faut considérer le
composant TDataSource comme le "tuyau" permettant la connexion entre les composants
représentants virtuellement la couche logicielle BDE ( composants TTable ou TQuery ) et les
composants de l'interface. Tous les problèmes de bufferisation des transferts de données, de
contrôle des accès, etc. sont gérés automatiquement par ces composants.
Les composants assurant la gestion interne des tables sont regroupés dans
l'onglet 'AccèsBD' de la palette de composants. Ceux permettant de créer
l'interface graphique et de manipuler les données sont placés dans l'onglet
'ContrôleBD '.
On peut par ailleurs utiliser un expert particulier pour construire des bases
simples. Mais les possibilités de cet utilitaire - en dehors de l'aspect
pédagogique - sont, somme toute, relativement limitées et rapidement
insuffisantes pour créer une application un tant soit peu professionnelle.
Il est rappelé que la structure complète de la base doit avoir été définie au
préalable et que les différentes tables ( ainsi que les clés utilisées et les liens
éventuels qui les unissent ) doivent avoir été créées dans DBD.
Page XII.16
Construction d'applications orientées données
Le composant TTable :
Ce composant fournit un accès "vivant" aux tables de la base de données, via BDE.
Il s'agit d'un composant "non visuel" qu'il faut déposer sur la feuille correspondant à
l'interface graphique puis qu'il s'agit de configurer. Il faut utiliser un composant
TTable par table accédée par l'application.
Le composant TDateSource :
Ce composant est l'interface entre un composant gérant l'accès aux données ( comme
TTable ) et les différents composants réalisant l'affichage des données.
Page XII.17
Construction d'applications orientées données
Il est souhaitable que le paramétrage initial soit réalisé avec la propriété Active à false
pendant toute la phase de conception. Une fois celle-ci réalisée, on peut basculer celle-ci
à true afin de pouvoir visualiser le contenu de la table ( si un composant d'interfaçage a
été paramétré pour cela ).
Cependant lorsque la mise au point initiale de l'application est faite il est préférable
qu'une table ne soit ouverte qu'à bon escient. De fait, une fois la configuration réalisée,
on remettra cette propriété à false et on ouvrira explicitement la table dans le
programme ( Table1->Active = true ou Table1->Open ( ) ).
Remarque importante :
Cette possibilité, qui nécessite quelques précautions dans sa mise en œuvre, est
très importante et permettra la constitution d'applications puissantes.
Page XII.18
Construction d'applications orientées données
spécificité est qu'ils sont "sensibles aux données". C'est à dire qu'ils sont en mesure
d'afficher le contenu d'un champ d'une table ou de modifier ce dernier.
Pour ce faire ils possèdent deux propriétés supplémentaires :
Les différents composants, affichent, dès la phase de conception (dans le cas où toutes
les connexions sont réalisées et que le composant TTable est actif ), les champs qui
correspondent du premier enregistrement de la table.
Exemple :
Le composant TDBNavigator :
Page XII.19
Construction d'applications orientées données
switch ( Button )
{
case nbFirst : Message = "Premier" ; break ;
case nbPrior : Message = "Précédent" ; break ;
case nbNext : Message = "Suivant" ; break ;
case nbLast : Message = "Dernier" ; break ;
case nbInsert : Message = "Insérer" ; break ;
case nbDelete : Message = "Supprimer" ; break ;
case nbEdit : Message = "Editer" ; break ;
case nbPost : Message = "Valider" ; break ;
Page XII.20
Construction d'applications orientées données
Le composant TDBGrid :
Ce composant est le plus utilisé dans le cadre de la gestion de base de données car il
permet d'afficher le contenu intégral d'une table sous forme d'un tableau. Il dispose
pour ce faire de beaucoup de possibilités.
Il est par ailleurs difficile de savoir quelle est la ligne et quelle est la
colonne que l'on vient de sélectionner dans une grille.
Page XII.21
Construction d'applications orientées données
TTable
Composant de l'interface
Composant de l'interface
Base
de
données
Form
Exemple :
Ouvrir un projet.
Initialiser un composant TTable avec les propriétés :
DataSet = TClients
Name = DSClients
Un composant TDBGrid
DataSource = DSClients
Name = DBGClients
Un composant TDBEdit
DataSource = DSClients
Name = DBEClientsName
Page XII.22
Construction d'applications orientées données
DataField = LAST_NAME
// Ce composant n'affiche qu'un champ
Un composant TDBNavigator
DataSource = DSClients
Name = TDBClients
Une fois cela réalisé il faut initialiser, dans la table dépendante les propriétés suivantes :
Page XII.23
Construction d'applications orientées données
Une fois cela réalisé on peut mettre les propriétés Active = true et exécuter
l'application. Chaque fois que l'on clique sur un enregistrement de la table maître, les
enregistrements liés dans la table "fille" sont affichés automatiquement.
- Ouvrir C++ Builder et créer un nouveau projet. Avant même de réaliser quoi que
ce soit l'enregistrer dans le répertoire du projet créé précédemment.
- Déposer 3 composants TTable et 3 composants TDataSource. Les initialiser
comme suit :
Page XII.24
Construction d'applications orientées données
- Lier les deux tables. Pour cela initialiser la propriété MasterSource du composant
TModeles avec le nom de la datasource de la table maîtresse ( MasterSource = DSTypes ).
Une fois cela fait, initialiser la propriété DataField ( qui correspond au champ liant les deux
tables, ici le champ IdType ). Cette initialisation se fait à l'aide d'une petite boite de dialogue
qui propose les liens à réaliser.
Par défaut, la boite propose les possibilités de liens susceptibles d'être réalisées
à l'aide de l'index primaire de la table ( = sa clé ).
Page XII.25
Construction d'applications orientées données
- Il suffit alors d'activer les deux tables et d'exécuter le programme pour que chaque
clic sur un item de la table TYPES affiche, dans la grille DBGModeles, les modèles – et que
les modèles - de ce type.
Très rapidement on va se rendre compte qu'une feuille peut devoir nécessiter l'accès à
un grand nombre de tables. Ces composants, même invisibles à l'exécution,
alourdissent considérablement l'interface de conception.
Par ailleurs plusieurs feuilles peuvent avoir, successivement, besoin d'accéder à la
même table.
Un module de données peut être créé via le menu 'Fichier | Nouveau ' qui affiche une
fenêtre 'Nouveaux éléments' dans laquelle apparaît une icône 'Module de données'. Quand se
choix est réalisé, une nouvelle fenêtre appelée Data Module, intégralement vide, apparaît dans
le projet. Cette fenêtre est à considérer comme une unité particulière dans laquelle on pourra
déposer les différents composants invisibles constituant les sources de données, qui ne pourra
cependant pas être appelée pour affichage par le programme.
Page XII.26
Construction d'applications orientées données
Il faut donner un nom explicite au Data Module. Comme toute unité, un fichier en-tête
d'extension .h lui est associé et contient les déclarations des différents composants déposés
(mais il n'y a pas de fichier .dfm associé ).
Il suffit de référencer le fichier en-tête du module de donnée dans les feuilles qui ont
besoin d'accéder aux composants qui y sont contenus ( comme cela est le cas lorsque l'on
souhaite accéder à un composant contenu dans une autre feuille ).
L'accès aux différentes propriétés et méthodes des composants contenus dans le module
se fera donc en utilisant une écriture du type :
Même si l'écriture des lignes de programmes est rendu un peu plus complexe que si
les composants sont déposés directement sur une feuille les utilisant, il faut
reconnaître que l'utilisation de modules de données se révèle incontournable dès que
l'application est amenée à manipuler un nombre important de tables.
Il peut être utile alors d'utiliser un composant spécifique, le composant TDataBase, qui
va permettre de donner à la base de données un certains nombre de caractéristiques globales.
Les deux propriétés principales de ce composant sont :
Page XII.27
Construction d'applications orientées données
Page XII.28