Analyse des séparations Java-/-Oracle

publicité
PizzaLand
Partie Java
GUYENNE Jean-Baptiste, THIRUCHELVAM Bannuchan
Groupe 332
PizzaLand | 2
Résumé
Dans le cadre du S3 et du projet Java/BD, il nous a été demandé de concevoir la suite de la gestion du site de la
pizzeria que nous avions étudiée en ACSI et Programmation Web. L’application devra permettre la gestion
intere de la pizzeria, à savoir, l’affichage pour les cuisiniers des commandes à honorer, la gestion des stocks
d’ingrédients,..
La gestion complète du système reposera sur un ensemble de 4 interfaces :
-
L’interface de cuisine, c’est la base même de la chaîne de production. Elle affichera la liste des
commandes (avec leurs détails) à honorer et permettra d’indiquer qu’une commande est en cours de
préparation ou prête. Les commandes y seront triées par ordre d’urgence, c’est-à-dire, les commandes
effectuées il y a plus longtemps en tête de liste.
L’interface devra permettre aux cuisinier de modifier l’état d’une commande : la commande passera
successivement par les états ‘non préparée’, ‘en préparation’, ‘prête à être livrée’.
L’interface devra également permettre aux cuisiniers de supprimer une commande (au cas où le client
voudrait l’annuler).
-
L’interface des livreurs encore à la pizzéria. Elle permet au livreur d’être tenu au courant des
commandes prêtes à être livrées ainsi que l’adresse de livraison.
En saisissant un numéro de commande, le livreur verra s’afficher l’adresse de livraison ainsi que l’heure
maximale à laquelle la commande doit être livrée pour ne pas être en retard.
-
L’interface des livreurs au moment de la livraison. Elle affichera l’adresse, le numéro de commande et
indiquera également si le client avait payé sa commande à l’avance.
-
L’interface du gestionnaire, qui lui permettra d’avoir un historique des ingrédients consommés sur une
période donnée, le chiffre d’affaire d’une période donnée, de planifier des commandes d’ingrédients,..
PizzaLand | 3
SOMMAIRE
Résumé
2
Schéma relationnel
4
Analyse des séparations Java-/-Oracle
5
Diagramme des classes Java
5
Exemple d’utilisation d’accès à la base de données
6
Guide d’utilisation
7
Code de l’interface cuisinier
8
Code de l’interface livreur (encore à la pizzeria)
12
Code de l’interface livreur (en livraison)
12
Code de l’interface gestionnaire
12
Amélioration à effectuer
13
Problèmes rencontrés
13
Compte-rendu
14
PizzaLand | 4
Schéma relationnel
Grâce à l’analyse préliminaire de conception que nous avions effectuée pour la partie ACSI et Programmation
Web de la pizzéria, nous avons pu établir le schéma relationnel qui convenait à nos besoins :
Comme indiqué lors de la Programmation Web, la gestion des boissons a été retirée afin de se concentrer sur
les pizzas. La table STOCK, bien que l’utilité immédiate soit limitée, est une étape vers ce qui nous serait
nécessaire pour gérer les boissons et autres produits.
PizzaLand | 5
Analyse des séparations Java-/-Oracle
-
-
-
-
Nous essayerons de minimiser la présence de code SQL dans le code source Java.
Nous tâcherons ainsi d’utiliser au maximum la création de fonctions et procédures stockées PL/SQL.
Ainsi les différentes sélections, insertions, mise à jour, suppression,.. dans la base de données se
feront au possible grâce à des fonctions et procédures stockées.
Les boutons de l’interface appelleront des procédures ou fonctions du modèle associé qui appelleront
à leur tour des procédures ou fonctions PL/SQL (via des CallableStatement, PreparedCall,..).
Pour la gestion des différentes alertes, comme par exemple la présence d’un nombre de commandes
élevé (>20), nous utiliserons des triggers.
L’application se chargera via un scan, régulier ou manuel, de la table d’alerte, de vérifier si une
nouvelle alerte a été insérée. Dans ce cas, un message fortement visible apparaîtra à l’écran du
gestionnaire et des cuisiniers.
Pour l’affichage de l’heure maximale de livraison, nous ferons le calcul de cette heure via le code Java.
Cela permet de libérer le serveur de la base de données d’un calcul qui pourrait être évité.
Le code Java récupèrera donc l’heure de commande, lui ajoutera 30 minutes, et c’est cette nouvelle
heure qui sera affichée au livreur.
Au moment de la livraison, ce n’est pas le livreur qui indiquera lui-même si la commande a été livrée
avec ou sans retard. Le livreur ne fera qu’indiquer l’heure de livraison, via l’interface dédiée à la
livraison, et grâce à un trigger s’occupera de calculer le nouveau statut de la commande (livrée avec
retard, livrée sans retard).
Diagrammes des classes Java
PizzaLand | 6
Exemples d’utilisation d’accès à la base de
données
-
Mise à jour de l’état d’une commande :
//Procédure qui appelle une procédure stockée pour mettre à jour l'état d'une
commande
//Paramètres :
//int commande : numero de la commande concernée
//String etat : nouvel état désirée ('en préparation', 'prête')
public void updateEtat(int commande, String etat) throws SQLException {
CallableStatement call = connection.prepareCall("call
updateStateCommande(?,?)");
//On assigne les différents paramètres puis on exécute
call.setInt(1, commande);
call.setString(2, etat);
call.execute();
}
Avec une la commande suivante
VALUES(427,1,4,8,7,1,1,SYSDATE,null,28); (1,1,4,8,7,1,1,SYSDATE,null,28)
(==> (commande,panier,client,cuisinier,livreur,statut,paiement,dateCommande,dateLivraison,prix))
En appelant la procédure updateEtat(427,’livrée avec retard’), l’état de la commande va donc changé
afin de faire correspondre son numéro d’état au numéro correspondant à l’état «livrée avec retardé ».
La commande
PizzaLand | 7
Guide d’utilisation
(Le guide sera effectué sur des maquettes ressemblant au possible au résultat souhaité).
Le bouton est grisé car la est
déjà dans l’état ‘en
préparation’.
Le bouton est grisé car la commande n’est
pas encore passé par l’état ‘en préparation’.
Le bouton sert à indiquer que le
cuisinier prend en charge cette
commande.
Le bouton sert à indiquer que la
commande est prête à être livrée.
PizzaLand | 8
Code de l’interface cuisinier
a) Modèle
package cuisinier.modeles;
import java.sql.*;
import java.util.ArrayList;
import java.util.Observable;
import java.awt.Toolkit;
import java.util.Timer;
import java.util.TimerTask;
public class ModeleCuisinier extends Observable{
Connection connection; //Connexion à la base de données
ArrayList<String[]> listeCommande; //Liste qui stockera les différentes commandes
int cuisinier=-999; //Servira à dire quel cuisinier est sur le poste
Toolkit toolkit; //Nécessaire pour le timer d'actualisation de la liste des commandes
Timer timer; //Nécessaire pour le timer d'actualisation de la liste des commandes
//Instanciation du modèle des cuisiniers
//Connexion à la base de données
ModeleCuisinier() throws SQLException{
listeCommande = new ArrayList<String[]>();
try{
Class.forName("oracle.jdbc.OracleDriver");
String url ="jdbc:oracle:thin:jguyenn/[email protected]:1521:etudom";
connection = DriverManager.getConnection(url);
}catch(ClassNotFoundException cnfe){
System.out.println("La classe JDBC n'a pas été trouvée");
cnfe.printStackTrace();
}
}
//Procédure qui met à jour la liste des commande à honorer
//Sera appelée via un bouton "Rafraîchir" et à chaque tick du timer
public void updateListeCommande() throws SQLException{
listeCommande.clear(); //On vide la liste actuel
String[] commande=new String[5]; //Création du tableau de String qui va contenir toutes les commandes
en cours
// commande[0] Numéro de commande
// commande[1] Numéro de client
// commande[2] Date de commande
// commande[3] Montant total de la commande
// commande[4] Liste des pizzas de la commande sous la forme
//
quantitex taille-type Aucun suppléments \n
//
quantitex taille-type Supplément(s) : supplement1 (,
supplement2) (, supplement3)
commande[0]="";
commande[1]="";
PizzaLand | 9
commande[2]="";
commande[3]="";
commande[4]="";
//Sélection des commandes à honorer et tri par priorité de date de commande
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery(
"SELECT DISTINCT numCommande,client,dateCommande,COMMANDE.prixTotal FROM
COMMANDE,STATUT"
+" WHERE statut=STATUT.numStatut AND libelleStatut IN ('non préparée','en préparation')
ORDER BY dateCommande DESC");
while(rs.next()){
commande[0]=rs.getString(1);//Stockage du numéro de commande
commande[1]=rs.getString(2);//Stockage du numéro de client
commande[2]=rs.getString(3);//Stockage de la date de commande
commande[3]=rs.getString(4);//Stockate du montant total de la commande
commande[4]="";
//Pour chaque commande trouvée, on recherche les différentes pizzas associées à cette commande
Statement statement2 = connection.createStatement();
ResultSet rs2 = statement2.executeQuery(
"SELECT quantite, libelleFormat,libelleType,supple1,supple2,supple3"
+" FROM COMMANDE,PANIER,LIGNEPANIER,FORMATPIZZA,TYPEPIZZA,PIZZA"
+" WHERE COMMANDE.numPanier=PANIER.numPanier"
+" AND PANIER.numPanier=LIGNEPANIER.numPanier"
+" AND LIGNEPANIER.numPizza=PIZZA.numPizza"
+" AND PIZZA.numFormat=FORMATPIZZA.numFormat"
+" AND PIZZA.numType=TYPEPIZZA.numType"
+" AND numGarniture=supple1"
+" AND numGarniture=supple2"
+" AND numGarniture=supple3"
+" AND COMMANDE.numCommande="+commande[0]);
while(rs2.next()){
//Pour chaque pizza différente trouvée, on l'ajoute aux pizzas de la commande
commande[4]=commande[4]+rs2.getString(1) + "x " + rs2.getString(2) + "-" +rs2.getString(3);
//On regarde si elle en a au moins 1
//On concatène les suppléments trouvés à la pizza
if(rs2.getInt(4)==0) {
commande[4]=commande[4] + " Aucun suppléments";
}
else {
commande[4]=commande[4] + "Supplément(s) : "+ rs2.getString(4);
if(rs2.getInt(5)!=0) {
commande[4]=commande[4] + ", "+ rs2.getString(5);
if(rs2.getInt(6)!=0) {
commande[4]=commande[4] + ", "+ rs2.getString(6);
}
}
}
commande[4]=commande[4]+" \n ";
}//fin sélection pizza d'une commande
listeCommande.add(commande);//On ajoute la commande à la liste des commandes
PizzaLand | 10
}//fin sélection liste commandes
}
//Procédure qui appelle une procédure stockée pour mettre à jour l'état d'une commande
//Paramètres :
//int commande : numero de la commande concernée
//String etat : nouvel état désirée ('en préparation', 'prête')
public void updateEtat(int commande, String etat) throws SQLException {
CallableStatement call = connection.prepareCall("call updateStateCommande(?,?)");
//On assigne les différents paramètres puis on exécute
call.setInt(1, commande);
call.setString(2, etat);
call.execute();
}
//Fonction qui appelle un fonction stockée pour savoir si l'utilisateur de l'interface a bien rentré ses identifiants
//et vérifie si il est membre du personnel
//Paramètres :
//String login : login rentré par l'utilisateur
//String password : mot de passe rentré par l'utilisateur
//Retour : "OK" || "Pas OK"
//En fonction du résultat, on passera (ou non) de l'interface d'identification à l'interface des pizzaiolos
//et on gardera le numéro du cuisinier en mémoire
public String connection(String login, String password) throws SQLException {
CallableStatement call = connection.prepareCall("{? = call identification(?,?) }");
//On identifie le type de retour
call.registerOutParameter(1,Types.VARCHAR);
//On assigne les différents paramètres puis on exécute
call.setString(2, login);
call.setString(3, password);
call.execute();
return call.getString(1);
}
//Programme main de tests au développement
public static void main(String[] args) throws SQLException {
ModeleCuisinier modele=new ModeleCuisinier(); //Instanciation du modèle
modele.updateListeCommande(); //mise à jour de la liste des commandes à honorer
//Push::faudra faire un refresh de la liste
//genre jtablecomm.clean()
//for int i=0, i<arraylistcomm.size(), i++
//
arraylistcomm.getitem(i);
//
for int j=0, j<5, j++
//
jtablecomm.ligne(i).subitem(j)=arraylistcomm.getitem(i)[j];
//
//faut trouver les vraies méthodes par contre
//test rafraichissement auto sur timer ::
}
}
PizzaLand | 11
b) Vue
package cuisinier.vues;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.border.MatteBorder;
public class VueCuisinier extends JFrame{
public static void main(String[] args) {
//Création de la fenêtre
JFrame mainFrame = new JFrame("PIZZALAND DE PONEYCITY");
//Création de la JTable qui va contenir la liste des commandes à honorer
JTable tableCommande = new JTable(15,8);
Color test=new Color(150,100,150);
tableCommande.setGridColor(test);
tableCommande.setRowHeight(75);
//Ajout de la liste à la fenêtre
mainFrame.add(tableCommande);
/////////////////////////////////////
//tests
//
JLabel label = new JLabel(new String("test") );
mainFrame.add(label,BorderLayout.NORTH );
/////////////////////////////////////
//Paramètres de la fenêtre
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(1000,800);
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
}
}
PizzaLand | 12
c) Contrôleur
package cuisinier.controleurs;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ControleurCuisinier implements ActionListener{
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
//agr0 cest le bouton qui lance l'actionperformed
//if arg0.gettext()= "en prépa" then modele.updateEtat(JTableCommandes.getSelectedLine().getItem(0)
<correspondant numCommande>> ,'en préparation')
//if arg0.gettext()= "pret" then modele.updateEtat(JTableCommandes.getSelectedLine().getItem(0)
<correspondant numCommande>> ,'prête à être livrée')
}
}
Code de l’interface livreur (encore à la
pizzeria)
Code de l’interface livreur (en livraison)
Code de l’interface gestionnaire
PizzaLand | 13
Problèmes rencontrés
-
Malgré une configuration inchangée, SQLDeveloper ne voulait plus se connecter au serveur distant.
Nous remercions le CCRI pour l’aide apportée pour résoudre ce problème.
-
Pour une même requête, Eclipse et SQLDeveloper ne nous retournait pas le même résultat.
Par exemple le plus souvent, Eclipse nous afficher des doublons alors qu’il n’était pas censé y en avoir.
-
La transition de notre ancienne base de données de la partie Programmation Web, en mysql, à la
nouvelle base, sous Oracle, a entrainé des pertes de temps importantes , notamment pour tout les
changements de types non supportés, la syntaxe des contraintes,..
-
Eclipse plante encore plus souvent qu’à l’IUT > perte de temps mineures mais présentes tout de même.
-
Parfois, au bout d’un moment, Eclipse n’affiche absolument aucun résultat quelle que soit la requête
exécutée (ex : SELECT * FROM XX)
Améliorations à effectuer
-
Partie BD :
La création de packetages distincts, gérant chacun des aspects spécifiques de la pizzeria, serait utile.
Création d’une fonction PL/SQL pour sélectionner toutes les commandes, plutôt que de le faire dans le
code Java.
Partie Java :
Le projet n’ayant pas suffisamment avancé, nous ne pouvons pas dire quelles améliorations seraient à
apporter.
PizzaLand | 14
Compte-rendu
Suite à une très mauvaise organisation, nous nous retrouvons avec très peu de travail effectué ; ce qui est
dommage car nous nous faisions une joie à l’avance de travailler sur un projet concret en Java, qui nécessitait
toutes nos connaissances en BD, et qui était la continuité du projet Pizzeria que nous avions déjà commencé.
C’est dans ces moments que l’on se rend compte l’importance de la contrainte de temps dans la réalisation d’un
projet.
Téléchargement