Table des matières

1. Persistance des données

1.1 généralités

  • Exemples :
    • Les données liées à l'utilisateur (données personnelles, sauvegardes,…)
    • Les données de l'entreprise:
      • données comptables
      • ventes
      • achats
      • employés
      • stocks
      • production
      • etc..
    • Bases d'information:
      • Documents en ligne
      • Services (trajets SNCF, articles commerciaux à vendre, données météo, articles de presse…)
    • Échanges et communication
      • index web (moteurs de recherche)
      • graphes de liens et messages (réseaux sociaux)

Donnée informatique

Serveur de bases des données

En informatique, une requête (en anglais query) est une demande de consultation, effectuée par un programme client à l’attention d’un programme serveur.

La requête peut être une simple référence vers un fichier, ou être l’expression d’une recherche plus spécifique (consultation de certaines fiches d’un fichier, croisement d’information (entre plusieurs fichiers), etc…). Dans ce cas, il est nécessaire d’utiliser un langage de requête (le plus souvent SQL).

Lors d’une consultation de type lecture/recherche, il y a souvent plusieurs réponses qui correspondent à la demande. Le résultat d’une requête prend donc la forme d’un ensemble de réponses. Ces réponses sont éventuellement classées, selon la valeur d’un certain identifiant, ou selon le degré de pertinence.

Exemples :
  • requêtes http : demande de consultation d’une page web ( = référence vers un fichier)
  • moteur de recherche : recherche de pages contenant les mots-clés spécifiés
  • bases de données : utilisation d’un langage de requête :
SELECT *
FROM  Eleves
WHERE NOM = 'Dugenou'

1.2. La mémoire cache

Rappel sur les fichiers

Lecture

f = open("/chemin/vers/mon_fichier", "r")

* f est un objet qui implémente un flux de données. * Un flux de données est structure d'accès :

* On parle d'accès séquentiel aux données

SCHEMA : TODO
s = f.readline()
SCHEMA : TODO

* Le système d'exploitation se charge de gérer la mémoire cache :

Ecriture

g = open("/chemin/vers/mon_fichier", "w")

autres possibilités :

g.write(s)
g.close()
g.flush()

Accès aux bases de données

import sqlite3
db = sqlite3.connect("/chemin/vers/mabase.db")
c = db.cursor()
c.execute("SELECT * FROM MaTable")
t = c.fetchone()
c.execute("INSERT INTO MaTable VALUES (v1, v2, v3)")
db.commit()

Appariement (Mapping) Objet/Données

Voir aussi : transparent_persistence.html

Exemples

Dans les deux premiers cas que nous avons vus, la gestion de la mémoire cache est déléguée à des programmes tiers:
  • Les système d'exploitation (pour la gestion des fichiers)
  • Le gestionnaire de BD (requêtes vers une BD)

Dans le cas du mapping Objet/Relationnel, la couche de persistance gère le chargement en mémoire des données de la base.

Elle joue le même rôle que la mémoire cache:

  • en maintenant en mémoire l'état des objets modifiés par l'utilisateur
  • en chargeant de manière parcimonieuse le contenu de la base (seuls les données réellement utilisées doivent être chargées en mémoire)

1.3 De la conception à la réalisation

Principe général : Retrouver le programme dans l'état dans lequel on l'a laissé lorsqu'on l'a précédemment quitté:
  • Les variables et objets manipulé sont régulièrement sauvegardés
  • Pour plus d'efficacité, le fichier de sauvegarde est une base de données
  • Au niveau de la conception du programme, on doit distinguer les données persistances des données non-persistantes
  • Mise en correspondance et synchronisation entre les donnée du programme et la base de données
  • Maintien de la cohésion assuré par la mémoire cache (interface entre application et SGBD)

Les données persistantes sont conservées dans une base de données relationnelle dont le schéma est établi au cours de l'étape de modélisation.

Modèle Entité/Association

Passage au modèle Relationnel

Création de tables SQL

  CREATE TABLE Enseignant (
    e_mail_ens VARCHAR(30) NOT NULL,
    nom VARCHAR(30) NOT NULL,
    prénom VARCHAR(30) NOT NULL,
    tel VARCHAR(12),
    PRIMARY KEY (e_mail_ens));
  CREATE TABLE UE (
    code_UE VARCHAR(30) NOT NULL,
    intitulé VARCHAR(30) NOT NULL,
    semestre INTEGER NOT NULL,
    nb_crédits INTEGER NOT NULL,
    e_mail_ens VARCHAR(30) NOT NULL,
    PRIMARY KEY (code_UE),
    FOREIGN KEY (e_mail_ens) REFERENCES Enseignant);

etc…

Passage au modèle UML

Réalisation en Python

Pour chaque Entité une classe distincte.

class Enseignant:
    def __init__(self, e_mail_ens , nom, prénom, tel):
        self.e_mail_ens = e_mail_ens
        self.nom = nom
        self.prénom = prénom
        self.tel = tel
        self.responsabilités = set()
        self.séances = set()
 
    def ajoute_seance(self, séance):
        self.séances.add(séance)
 
    def ajoute_responsabilité(self, UE):
        self.responsabilités.add(UE)

etc…

Mise en œuvre de la persistance : patron DAO

Un DAO (Data Access Object) est une classe qui réalise l'interface entre une classe d'objets persistants et la base de données.

Dans l'exemple considéré, on doit donc avoir les six classes suivantes:
  • Enseignant_DAO
  • UE_DAO
  • Séance_DAO
  • Elève_DAO
  • Examen_DAO
Il est possible de mettre en œuvre un patron de conception Factory permettant de gérer les différentes interfaces au sein d'une même classe en évitant la répétition de code
En Python:
class Enseignant_DAO:
    def __init__(self, db_name):
        self.db = sqlite3.connect(db_name)
    def create_enseignant(self, enseignant):
        ...
    def get_enseignant_by_id(self, id_enseignant): # Read
        ...
    def update_enseignant(self, enseignant):
        ...
    def delete_enseignant(self, enseignant):
        ...
Remarque : l'opération de lecture get_enseignant_by_id effectue les opérations suivantes:
  • extraction des données de l'enseignant dans la table Enseignant:
c.execute("SELECT * FROM Enseignant WHERE e_mail_ens = ?", (id_enseignant,)) 
  • initialisation un objet enseignant (à l'aide du constructeur de la classe Enseignant)
  • recherche des séances programmées dans la table Séances:
c.execute("SELECT id_séance FROM Séance WHERE e_mail_ens = ?", (id_enseignant,)) 
  • pour chaque id_séance trouvé,
    • initialise un objet de type Séance avec la méthode get_séance_by_id de la classe Séance_DAO
    • ajoute la séance dans l'ensemble séances avec la méthode ajoute_seance de l'objet enseignant
  • recherche des responsabilités d'UE dans la table UE:
c.execute("SELECT code_UE FROM UE WHERE e_mail_ens = ?", (id_enseignant,)) 
  • pour chaque code_UE trouvé,
    • initialise un objet de type UE avec la méthode get_UE_by_id de la classe UE_DAO
    • ajoute l'UE dans l'ensemble responsabilités avec la méthode ajoute_UE de l'objet enseignant
  • retourne l'objet enseignant
Problème : avec le patron DAO, l'existence de relations many-to-many a pour effet de charger l'intégralité des tables concernées en mémoire lors de la lecture d'un objet unique!!

Exemple : relation many-to-many entre Elève et Séance :

  • La méthode get_séance_by_id fait appel à get_eleve_by_id pour établir la liste de présence
  • La méthode get_eleve_by_id fait appel à get_séance_by_id pour établir la liste des séances auxquelles l'élève a assisté
  • etc….

Il faut donc prévoir de ne charger qu'une partie des informations, celle qui est réellement utile au programme (inutile de charger l'emploi du temps de chaque élève lorsqu'on s'intéresse à la liste de présence d'une séance particulière).

  • Avec le patron DAO, il faut gérer au cas par cas
  • Les Gestionnaires de persistance ORM (django, Pony ORM) permettent de gérer le chargement des données "à la demande", à la manière de la mémoire cache.

Voir aussi : dao-et-orm-sont-ils-compatibles

Un gestionnaire de persistance : la librairie Pony ORM

2. Le patron MVC (Modèle-Vue-Contrôleur)

Le patron de conception "Modèle - Vue - Contrôleur" est destiné à faciliter le développement d'interfaces graphiques.

Une Interface graphique est constituée essentiellement de deux modules :

Pour développer un tel programme, on le divise généralement en trois modules appelés respectivement:

Le Modèle

Le modèle est la partie du programme qui manipule et met à jour les informations qui doivent être conservées d'une session à l'autre. Il s'agit de l'ensemble des variables et objets qui sont créés et mis à jour par l'utilisateur lorsqu'il interagit avec le programme.

La Vue

La Vue est la partie du programme qui gère la mise en page, la disposition des informations, des boutons et des formulaires, l'organisation et la visibilité des différentes fenêtres du programme s'il y en a.

Le Contrôleur

Le contrôleur est la partie du programme qui gère les actions de l'utilisateur. Chacune des actions proposées dans la vue est implémentée dans le contrôleur sous la forme d'une fonction.

Voir aussi

3. Développement Web

Le Web est basé sur trois piliers :

  • Le Web englobe les sites qui peuvent être consultés dans un navigateur, et n'est qu'une des briques de l'Internet
  • Parmi les autres :
    • le courrier électronique
    • les applications mobiles
    • etc.

(source:Libération du 19/01/2011)

3.1 Généralités

Client/Serveur

HTML + CSS

Pages dynamiques

Web dynamique

Principe général : consultation/mise à jour à distance d'une base de données.

Remarque : 3 langages sont nécessaires pour réaliser ce schéma:
  • Un langage d'édition de pages Web (interprété côté client):
    • en général langage HTML (ou HTML + CSS)
    • agrémenté de différentes librairies de mise en forme:
    • Les seuls langages compréhensibles pour le navigateur sont HTML et CSS et Javascript
  • Un langage de développement (interprété côté serveur)
    • Le choix est vaste (n'importe quel langage de programmation)
    • Les plus courants sont (par ordre de popularité):
      • PHP
      • Java (avec la librairie Spring MVC)
      • Python (avec la librairie Django)
      • Javascript (librairie Node.js)
      • etc.
  • Un langage de requêtes (interprété côté serveur):
    • pour communiquer avec la base de données et enregistrer les mise à jour
    • Le SQL dans 90% des cas
    • Mais d'autres alternatives sont possibles (NoSQL): MongoDB, etc…

3.2 HTML

Un document HTML contient deux parties :

Structure d'une page en HTML 5

De nombreuses ressources web sont disponibles pour apprendre le HTML, voir par exemple html

Exemple

emmanuel.dauce.free.fr

Aide-mémoire
  • En-tête:
    • <head> . . . </head>
    • <meta http−equiv="Content−Type" content="text/html; charset=utf−8" />
    • <title> . . . </title>
    • <link rel="stylesheet" href="style.css" type="text/css" />
  • Corps:
    • Bloc:
      • <body> . . . </body>
      • <p> . . . </p>
      • <h1> . . . </h1>, <h6> . . . </h6>
      • <div> . . . </div>
    • Flux:
      • <br />
      • <hr />
      • <em> . . . </em>, <strong> . . . </strong>
      • <span>. . . </span>
    • Listes:
      • <ol><li> . . . </li> . . . </ol>
      • <ul><li> . . . </li> . . . </ul>
      • <dl><dt> . . . </dt><dd> . . . </dd> . . . </dl>
    • Tables:
      • <table> . . . </table>
      • . . .

      • <tr> . . . </tr>
      • <th> . . . </th>
      • <td> . . . </td>
    • Images:
      • <img src="image.png" alt ="texte alternatif " />
    • Liens et ancres:
      • <a href="http://www.cnrs.fr/"> . . . </a>
      • <baliseid="toto"> . . . </balise>
      • <a href="#toto"> . . . </a>
    • Attributs communs à toutes les balises:
      • style
      • class
      • id

3.3 CSS

3.4 Transfert de données

Transmission de données "en clair"

Variables GET :

  http://mon.adresse.com/mon_site.php?nom=Pignon&prenom=Francois
       A D R E S S E      RESSOURCE       V A R I A B L E S
  

Le serveur exécute le script (php, python, java, …), c'est à dire :

Transmission de données par formulaire

Variables POST (n'apparaissent pas dans l'URL)

<FORM method="post" action="cible.php"> 
    ... 
</FORM>

les balises INPUT définissent les variables à transmettre:

<INPUT type="text" name="var1" />

l'INPUT de type submit lance la requête : la page cible est chargée et remplace la page courante:

<INPUT type="submit" value="Envoyer" />

Exemple

<form action = "bonjour.php" method ="post">
Votre nom : <input type="text" name="nom"/> <br/>
Votre prénom : <input type="text" name="prenom"/> <br/>
<input type="submit" value="Envoyer">
</form>
echo "Bonjour, ".$_POST["prenom"]." ".$_POST["nom"]." !!!";
Aide-mémoire formulaires
  • <form method="post" action="script.php" enctype="multipart/form−data">
  • </form>

(enctype peut être omis, il vaut alors application/x−www−form−urlencoded).

  • <fieldset> . . . </fieldset>
  • <legend> . . . </legend>
  • . . .
  • <input type="text" name="nom" value="défaut" maxlength="42" />
  • <input type="password" name="nom" value="défaut" maxlength="42" />
  • <input type="checkbox" name="nom[]" value="valeur" checked="checked" />
  • <input type="radio" name="nom" value="valeur" checked="checked" />
  • <input type="file" name="nom" />
  • <input type="hidden" name="nom" value="valeur" />
  • <input type="reset" value="étiquette" />
  • <input type="submit" value="étiquette" />
  • <textarea name="nom" cols ="80" rows="5"> . . . </textarea>
  • <select name="nom">
    • <option value="valeur1"> . . . </option>
    • <option value="valeur2" selected="selected"> . . . </option>
  • </select>

3.5 Conservation des données

  • Le patron MVC est devenu la norme pour le développement d'applications Web.
  • On pourra prendre exemple sur l'environnement de développement Django pour la mise en œuvre : 1871426-le-fonctionnement-de-django

3.6 Interfaces Mixtes

JQuery + AJAX

Exemples :

$.ajax({
    type: "POST",
    url: "test.html",
    success:
    function(retour){
        alert("Données retournées : " + retour );
    }
});
$("a.test").click(function() {
    $.ajax({
        type: "POST",
        url: $(this).attr("href"),
        success: function(retour){
            $("#recipient").empty().append(retour);
        }
    });
    return false;
});
$("form.test").submit(function() {
s = $(this).serialize(); 
$.ajax({
        type: "POST",
         data: s,
         url: $(this).attr("action"),
         success: function(retour){ 
            $("#recipient").empty().append(retour);
         }
     });
return false;
 });