ACCÈS À UNE BASE DE DONNÉES MYSQL VIA LAZARUS

 
ACCÈS À UNE BASE DE DONNÉES MYSQL VIA LAZARUS
TP Mysql avec Lazarus - page 1

       Accès à une base de données MySql via Lazarus

                    Première partie : exécution de requêtes
                             Auteur: E. Thirion - dernière mise à jour : 13/12/13

Ce TP (ou tutoriel si vous préférez) vous enseignera comment réaliser un projet Lazarus utilisant une base
de données MySQL. Nous utilisons toujours la base de données BDVol comme exemple. Il est donc
préférable de la regénérer à partir des liens Suppr BDVols et Créer BDVols du cours. D'autre part, le
serveur de base de donnée doit évidement fonctionner. N'oubliez donc pas de lancer Wamp avant
d'exécuter votre programme.

Le projet est à exécuter de A à Z, interface graphique comprise, dans le répertoire:

                                      Exo-ProgBD/TPMysqlLazarus1

Vous constaterez que ce répertoire contient déjà un fichier libmySQL.dll.           Il s'agit d'une dll qui est
indispensable pour la communication entre Lazarus et le serveur Mysql.
ACCÈS À UNE BASE DE DONNÉES MYSQL VIA LAZARUS
TP Mysql avec Lazarus - page 2

L'exécution de requête depuis un projet Lazarus se fait en utilisant des composants (ou classes)
spécialisées.

I - Mise en place des composants invisibles
Commencez par déposer les composants suivants sur votre formulaire:

Le composant Datasource se trouve dans l'onglet DataAccess. Vous trouverez les trois autres sous l'onglet
onglet SQLdb. Ces quatre composants doivent être liés de la manière suivante, en utilisant l'éditeur de
propriétés :

Le composant MySql51Connection contient les informations de connexion à la base de données: nom de
la base de données (propriété DatabaseName), URL du serveur (propriété Hostname), nom de l'utilisateur
(propriété UserName) et mot de passe (propriété Password). Dans ce TP, nous souhaitons nous connecter
à la base BDVols avec le serveur Mysql s'exécutant en local sur votre machine. Il faudra donc donner les
valeurs suivantes à ces propriétés :

                                     Propriété          Valeur
                                     DatabaseName       bdvols
                                     Hostname           localhost
                                     UserName           root
                                     Password
ACCÈS À UNE BASE DE DONNÉES MYSQL VIA LAZARUS
TP Mysql avec Lazarus - page 3

Le composant SQLQuery est une classe qui permet d'exécuter des requêtes, par l'application des méthodes
Open ou ExecSQL.

ExecSQL peut s'utiliser avec n'importe quel type de requête. Open, par contre ne peut s'utiliser qu'avec une
requête SELECT.

La méthode Open charge en mémoire une représentation de la table retournée par la requête SELECT. A
cette représentation est associé un curseur qui pointe à tout moment sur une ligne de la table.

II - Mise en place des composants visibles
Nous allons à présent mettre en place deux composants graphiques extrèmement puissants: DBGrid et
DBNavigator. En effet, nous allons voir que ces deux composants vont nous permettre d'afficher une table
et de la modifier en n'écrivant quasiment aucune instruction !

DBGrid permet d'afficher la table résultat d'une requête SELECT quelconque. On précise quelles colonnes
de cette table on souhaite afficher et comment elles doivent apparaitre à l'écran. Les colonnes peuvent être
des colonnes existantes dans la base de données ou des colonnes calculées.

DBNavigator quand à lui permet de modifier une table de la base de donnée. Il doit être utilisé avec un
DBGrid afin que l'utilisateur puisse facilement indiquer quelle ligne il souhaite modifier. Cela ne fonctionne
que dans un cas particulier: la requête SELECT associée au DBGrid doit dans ce cas utiliser une seule
table et la (ou les) colonne(s) constituant la clé primaire doivent être affichées.

Ces deux composants se trouvent sous l'onglet DataControls qui regroupe tous les composants graphiques
spécialisés dans l'accès aux bases de données.

Commencez par ajouter un composant DBGrid et un composant DBNavigator à votre formulaire, en les
reliant au composant DataSource de la manière suivante:
ACCÈS À UNE BASE DE DONNÉES MYSQL VIA LAZARUS
TP Mysql avec Lazarus - page 4

Définition des colonnes du DBGrid

Le composant DBGrid va nous servir à afficher la table Vols de la base de données. Pour cela il va falloir
définir quelles colonnes nous souhaitons afficher et comment nous souhaitons les afficher.

Sélectionnez le DBgrid, puis sur cliquez les ... de la propriété Columns. Cela ouvre l'éditeur de colonne:

Cliquez sur Ajouter. Vous obtenez une première colonne sans nom. Il faut maintenant lui donner un titre et
l'associer à une colonne de la table. Pour cela mettez le nom de la colonne dans la propriété Fieldname et
son titre dans la propriété Title.

Vous introduirez de cette manière les colonnes suivantes (toutes les colonnes de la table Vols) en procédant
de gauche à droite:

Titre                  Numéro               Date              Jour              Avion             Horaire
Colonne                NumeroV              Jour            JourSem             Avion             Horaire

Notez bien la différence entre le nom de la colonne (propriété FieldName) et son titre (propriété Title). La
première prorpiété est le nom exact de la colonne dans la base de donnée, alors que la seconde est le nom
visible de la colonne (c'est à dire celui qui sera affiché dans l'interface graphique).

Après avoir défini les cinq colonnes de la table Vols, votre éditeur de colonne devrait ressembler à ceci :

et votre interface graphique devrait ressembler à ceci :
ACCÈS À UNE BASE DE DONNÉES MYSQL VIA LAZARUS
TP Mysql avec Lazarus - page 5

III - Affichage de la table des vols dans le DBGrid

A présent, nous allons écrire un peu de code dans la procédure FormCreate. Ce code s'exécutera donc dès
le démarrage du programme. Le voici :

                   procedure TForm1.FormCreate(Sender: TObject);
                   begin
                     // Tentative de connexion à la base de données BDVols
                     MySQL51Connection1.Open;
                      if Not MySQL51Connection1.Connected then
                      begin
                         ShowMessage ('Connexion échouée !'); exit;
                      end;
                     // Affichage de la table Vols dans le DBGrid

                      SQLQuery1.SQL.Text:= 'SELECT * FROM Vols';
                      SQLQuery1.Open;

                   end;

L'instruction MySQL51Connection1.Open; effectue la connexion au serveur de base de données. Si la
connexion échoue ( MySQL51Connection1.Connected = false) le message 'Connexion échouée' est
affiché.

Les instructions suivantes font indirectement le lien entre la table Vols et le DBGrid. La requête "SELECT *
FROM Vols" retourne la table Vols. Pour pouvoir exécuter une requête, il faut d'abord la stocker dans
l'attribut SQL.Text d'un composant SQLQuery. D'où l'instruction:

                                SQLQuery1.SQL.Text:= 'SELECT * FROM Vols';

L'instruction suivante ( c'est à dire SQLQuery1.Open) envoi la table résultat en mémoire dans le composant
SQLQuery1, ce qui provoque automatiquement son affichage dans le DBGrid.

A présent lancer Wamp sur votre machine afin que le serveur MySql fonctionne. Ensuite saisissez le code de
la procédure FormCreate donnée ci-dessus, puis compiler votre programme.
ACCÈS À UNE BASE DE DONNÉES MYSQL VIA LAZARUS
TP Mysql avec Lazarus - page 6

Vous devriez en principe obtenir ceci :

IV - Modification de la table avec le DBNavigator

Le composant DBNavigator comporte dix boutons qui permettent de modifier une table sans rien (ou
quasiment rien) programmer. Ce sont les boutons suivants:

Vous constaterez que certains de ces boutons fonctionnent déjà : ce sont les boutons de navigation dans la
table. Ils vous permettent de déplacer le curseur dans la table: au début (First), en arrière (Prior), en avant
(Next) et à la fin (Last). Ici par exemple, le curseur est en position 5:
ACCÈS À UNE BASE DE DONNÉES MYSQL VIA LAZARUS
TP Mysql avec Lazarus - page 7

Le curseur permet d'indiquer sur quelle ligne de la table on souhaite agir via les autres boutons qui
permettent soit d'ajouter une ligne (le bouton Insert représenté par un +), d'en supprimer une (le bouton
Delete représenté par une poubelle) ou d'en modifier une (le bouton Edit représenté par un crayon):

    ●   Pour modifier une ligne: positionnez le curseur dessus, cliquez sur le bouton Edit, modifiez les
        valeurs que vous souhaitez changer, puis cliquer sur le bouton Post. Ce bouton permet de
        répercuter les modifications sur la base de donnée.

    ●   Pour ajouter une ligne: cliquez sur Insert, saisissez les valeurs de cette ligne, puis cliquez sur Post.

    ●   Pour supprimer une ligne: positionnez le curseur dessus, puis cliquez sur le bouton Delete.

Pour l'instant ces trois boutons ne fonctionnent pas: ils ne font que modifier la table stockée en mémoire et
ces modifications ne sont pas répercutées sur la base de données. Vous pouvez le vérifiez en utilisant le
bouton Refresh, qui reéxécute la requete SELECT et recharge la table en mémoire.

Pour que les modifications soient répercutées sur la base de données, il faut appliquer la méthode
ApplyUpdates au composant SQLQuery. Cette méthode, doit être appelée lorsque l'utilisateur a cliqué sur
les boutons Post ou sur Delete du DBNavigator. Ces actions de l'utilisateur génèrent des évènements
AfterPost et AfterDelete associés au composant SQLQuery. Il faut donc appeler la méthode AppyUpdate
dans les gestionnaires d'évènements AfterPost et AfterDelete de ce composant.

Voilà comment procéder:

    ●   Sélectionnez l'objet SQLQuery1.

    ●   Dans l'onglet Evènement selectionnez la propriété AfterPost et cliquez sur les ...

    ●   Puis ajoutez l'instruction SQLQuery1.ApplyUpdates(); dans la procédure évènementielle
        générée dans l'éditeur de source :

                 procedure TForm1.SQLQuery1AfterPost(DataSet: TDataSet);
                 begin
                   SQLQuery1.ApplyUpdates();
                 end;
ACCÈS À UNE BASE DE DONNÉES MYSQL VIA LAZARUS
TP Mysql avec Lazarus - page 8

    ●   De même, sélectionnez AfterDelete dans l'onglet Evènement.

    ●   Puis ajoutez l'instruction SQLQuery1.ApplyUpdates(); dans la procédure évènementielle
        générée dans l'éditeur de source :

                 procedure TForm1.SQLQuery1AfterDelete(DataSet: TDataSet);
                 begin
                   SQLQuery1.ApplyUpdates();
                 end;

Vous pourrez vérifier qu'à présent les trois boutons pour ajouter, supprimer ou modifier une ligne
fonctionnent (pour cela, vous pouvez par exemple visualiser la table vols avec PhpMyAdmin).

V - Exécution de requêtes sans utiliser DBNavigator

Nous allons voir ici comment exécuter des requêtes sans utiliser le composant DBNavigator.

V - 1 - Adjonction et suppression de lignes

Commencez par ajouter de nouveaux composants à l'interface graphique:

    ○   Un nouveau composant SQLQuery toujours associé à SQLTransaction1 et
        MySQL51Connection1.

    ○   Deux boutons intitulés Supprimer et Ajouter.

    ○   Cinq zones de texte intitulées Numéro, Date, Jour, Avion et Horaire.

Après ces modifications, votre interface graphique devrait ressembler à ceci:
ACCÈS À UNE BASE DE DONNÉES MYSQL VIA LAZARUS
TP Mysql avec Lazarus - page 9

L'objectif est de pouvoir supprimer ou ajouter un vol en utilisant les boutons Supprimer et Ajouter. Plus
précisément:

    ●   pour supprimer un vol: l'utilisateur saisi son numéro dans la zone de texte intitulée Numéro, puis
        clique sur le bouton Supprimer.

    ●   pour ajouter un nouveau vol, l'utilisateur saisi sa date (sous la forme AAAA-MM-JJ), le jour de la
        semaine (zone de texte intitulée Jour), le numéro de l'avion et le numéro de l'horaire, puis clique sur
        le bouton Ajouter. Attention: le numéro de vol n'est pas saisi, car il est incrémenté automatiquement
        à chaque insertion (voir requête INSERT dans le cours II sur les bases de données).

Voici le code incomplet de la procédure évènementielle associée au bouton Supprimer :

                        procedure TForm1.BT_SupprClick(Sender: TObject);
                        var numero: string;
                        begin
                           .....
                           SQLQuery2.SQL.Text :=
                           SQLQuery2.ExecSQL;
                           SQLQuery1.Refresh;
                        end;

Pour que cela fonctionne, il faut construire la requête de suppression (voir requête DELETE dans le cours II
sur les bases de données) à partir du numéro de vol et affecter cette requête à la propriété SQL.Text du
composant SQLQuery.

L'instruction SQLQuery2.ExecSQL sert à exécuter la requête. On applique pour cela la méthode ExecSQL
à ce même composant.

L'instruction SQLQuery1.Refresh rend les modifications sur la base de données visibles: elle rafraichi la
table chargée dans SQLQuery1, ce qui met automatiquement à jour le DBGrid qui lui est associé.

Pour le bouton Ajouter, vous pouvez utiliser le même principe avec cette fois-ci une requête INSERT.
ACCÈS À UNE BASE DE DONNÉES MYSQL VIA LAZARUS
TP Mysql avec Lazarus - page 10

V - 2 - Recherche multi-critères

On souhaiterait à présent afficher tous les vols vérifiant certaines conditions dépendants de l'heure de
départ, la ville de départ, l'heure d'arrivée et la ville d'arrivée.

V - 2 - a - Adjonction de nouveaux composants au formulaire

Vous allez pour cela complèter le formulaire de la manière suivante :

Il vous faudra donc ajouter:

    ●    Un nouveau DBGrid (DBGrid2), un nouveau DataSource (DataSource2) et un nouveau SQLQuery
        (SQLQuery3). Déposez ces trois composants sur le formulaire en les reliant comme indiqué dans le
        schéma page 3 et en réutilisant les composants SQLTransaction1 et MysQL51Connection1.

    ●   Un bouton Rechercher.

    ●   Quatre zones de texte pour saisir l'heure et la ville de départ ainsi que l'heure et la ville d'arrivée.

    ●   Un mémo (tout en bas) qui nous servira à afficher la requête SQL de recherche.

Le nouveau DBGrid servira à afficher tous les vols (par numéro, date, heure de départ, ville de départ, heure
d'arrivée, ville d'arrivée ) vérifiant certaines propriétés.
TP Mysql avec Lazarus - page 11

Nous allons donc afficher le résultat d'une requête SELECT de la forme:

  SELECT NumeroV, Jour, HeureDepart, VilleDepart, HeureArrivee, VilleArrivee
  FROM Vols, Horaires WHERE Vols.horaire=Horaires.numeroH AND Condition

où Condition est la condition de recherche.

Il s'agit d'une requête utilisant deux tables: la table Vols et la table Horaire dont le résultat sera une table à
six colonnes (NumeroV, Jour, HeureDepart, VilleDepart, HeureArrivee, VilleArrivee).

En utilisant l'éditeur de colonne. Définissez les titres de ces colonnes de la manière suivante:

Colonne            NumeroV            Jour        HeureDepart      VilleDepart    HeureArrivee     VilleArrivee
Titre               Numéro            Date           Départ            De            Arrivée             à
Largeur                60              70              50              70               50              70

Pour modifier la largeur, éditez la propriété width de la colonne. Pour centrer le contenu d'une colonne,
utilisez la propriété Alignment et sélectionez taCenter. Pour centrer le titre d'une colonne, utilisez la sous-
propriété Alignment de la propriété Title et sélectionnez la valeur taCenter.

V - 2 - b - Affichage de la table au démarrage du programme

Dans la procédure FormCreate, ajoutez les instructions permettant d'afficher tous les vols dans DBGrid2
dès le démarrage du programme.
TP Mysql avec Lazarus - page 12

V - 2 - c - Le bouton Rechercher

Pour la recherche, nous utiliserons les quatre nouvelles zones de texte. L'utilisateur n'est pas obligé de les
remplir toutes. Les zones de texte non renseignées seront simplement ignorées dans la recherche. Par
exemple, s'il renseigne simplement la ville de départ et l'heure d'arrivée comme suit:

il obtient tous les vols partant de Paris à n'importe quelle heure et arrivant (n'importe où !) à 14 heures. La
requête générant cette recherche est affichée dans le Mémo.

On vous demande ici de faire fonctionner le bouton Rechercher de cette manière. Quelques indications:

    ●   pour mettre une chaine de caractère dans un mémo, on affecte cette chaine à la proprité .Text du
        mémo.
    ●   avant de mettre la requete dans le composant SQLQuery, il faut rompre le lien avec l'ancienne
        requete en lui appliquant la méthode Close.
    ●   pour éviter une imbrication complexe de if dans la construction de la requête de recherche, je vous
        conseil de procéder de la manière suivante:

 requete := 'SELECT NumeroV, Jour, HeureDepart, VilleDepart, HeureArrivee, VilleArrivee '+
 'FROM Vols, Horaires WHERE Vols.horaire=Horaires.numeroH AND '+
  condHD + ' AND '+ condVD + ' AND ' + condHA+ ' AND ' + condVA ;

où condHD, condVD, condHA, condVA sont respectivement les conditions sur l'heure de départ, la ville de
départ, l'heure d'arrivée et la ville d'arrivée. Une condition qui n'intervient pas dans la recherche sera
simplement représentée par la chaine de caractères 'TRUE'. Cette méthode utilise le fait que la valeur TRUE
ne change rien dans un AND : TRUE AND x est équivalent à x. Par exemple pour ignorer la condition sur la
ville de départ, on affectera la valeur 'TRUE' à condHD.
Vous pouvez aussi lire
DIAPOSITIVES SUIVANTES ... Annuler