Gestion d'une Requête SQL grâce à JCBD

Gestion d'une Requête SQL grâce à JCBD - Java - Programmation

Marsh Posté le 24-01-2012 à 21:08:55    

Bonsoir à tous,
 
Pour ce premier post, je me permets de vous demander votre aide afin de réaliser une fonction dont je galère a réaliser depuis plus d'une semaine.
Je vous explique le contexte : Je dois réaliser un jeu de questions / réponses. Pour cela j'ai crée une base de données. J'ai donc créer une classe BaseDeDonnées qui a pour but de gérer les échanges entre mon application et ma base de données. La fonction en question doit permettre de mettre dans un vecteur de tableaux de strings (Vector<String[]> ) toutes les questions de la base ainsi que ses 4 réponses possibles, son thème et la bonne réponse. En effet le schéma (attributs) de la table Questions est le suivant : Intitulé Question, Thème, Bonne Réponse, Réponse 1, Réponse 2, Réponse 3 & Réponse 4.
 
Or je suis bloqué et je ne sais plus du tout comment m'y prendre. Je vous remercie par avance de votre aide :-)
 

Code :
  1. import java.sql.*;
  2. import java.util.Vector;
  3. public class BaseDeDonnees {
  4.     // import des variables pour la base de donnees postgres
  5.  private Connection connection_base = null;
  6.  private static ResultSet table_questions = null;
  7.  private Statement        sql;       // Our statement to run queries with
  8.  private DatabaseMetaData dbmd;
  9.   public BaseDeDonnees() throws SQLException {
  10.   // chargement du pilote
  11.      try {
  12.       Class.forName("org.postgresql.Driver" );
  13.      } catch (ClassNotFoundException e) {
  14.         arret("Impossible de charger le pilote jdbc:odbc" );
  15.      }
  16.    
  17.      //connection a la base de données
  18.      affiche("Connexion à  la base de données en cours..." );
  19.      try {
  20.         String DBurl = "jdbc:postgresql://postgres-info/bdbaret";
  21.         connection_base = DriverManager.getConnection(DBurl, "userbaret", "pbaret" );
  22.      } catch (Exception e) {
  23.         arret("Connection à  la base de données impossible" );
  24.      }
  25.    
  26.      dbmd = connection_base.getMetaData();
  27.      sql = connection_base.createStatement();
  28.    
  29.    //creation et execution de la requete
  30.      affiche("Création et execution de la requête" );
  31.      String requete = "SELECT * FROM Question";
  32.      try {
  33.      table_questions = sql.executeQuery(requete);
  34.      } catch (SQLException e) {
  35.      arret("Anomalie lors de l'execution de la requête" );
  36.      }
  37.    
  38. }
  39.   private static void affiche(String message) {
  40.       System.out.println(message);
  41.    }
  42.    private static void arret(String message) {
  43.       System.err.println(message);
  44.       System.exit(99);
  45.    }
  46.    public Vector<String[]> getListeQuestions() throws SQLException {
  47.     ResultSetMetaData rsmd = table_questions.getMetaData();
  48.        int nbCols = rsmd.getColumnCount();
  49.        Vector<String[]> Vecteur = new Vector<String[]>();
  50.        String Tableau [] = new String[6];
  51.        while(table_questions.next()) {
  52.         for (int i = 1; i <= nbCols; i++) {
  53.          Tableau[i-1] = table_questions.getString(i).toString();
  54.         }
  55.         Vecteur.add(Tableau);
  56.        }
  57.        return Vecteur;
  58.    }
  59. }


Message édité par Sylvain38220 le 24-01-2012 à 21:14:12
Reply

Marsh Posté le 24-01-2012 à 21:08:55   

Reply

Marsh Posté le 26-01-2012 à 23:24:57    

Salut Sylvain38220,
 
Tu ne décris pas très bien ton problème mais en regardant ton code on peut essayer de deviner pourquoi tu n'arrives pas à l'expliquer. Le principal problème de ta classe est que tu absorbes les exceptions qui pourtant pourraient te donner pas mal d'informations sur la cause du dysfonctionnement. Au lieu de faire :

Code :
  1. try {
  2.    String DBurl = "jdbc:postgresql://postgres-info/bdbaret";
  3.    connection_base = DriverManager.getConnection(DBurl, "userbaret", "******" );
  4. } catch (Exception e) {
  5.    arret("Connection à  la base de données impossible" );
  6. }


Je te suggères plutôt de faire :

Code :
  1. String DBurl = "jdbc:postgresql://postgres-info/bdbaret";
  2. try {
  3.    connection_base = DriverManager.getConnection(DBurl, "userbaret", "******" );
  4. } catch (SQLException e) {
  5.    System.err.println("Connexion à la base de données impossible" );
  6.    throw e;
  7. }


Si DriverManager lance une exception SQLException elle doit contenir au moins un message d'erreur qui pourrait te permettre de diagnostiquer le souci. Tu peux très bien afficher le message d'erreur de ton choix sur la sortie d'erreur mais il faut absolument re-throw l'exception afin que l'appelant en sache davantage.
 
Je vois pas mal d'autres problèmes dans ton code. Par exemple :

  • le membre table_questions est static : il n'a aucune raison de l'être et c'est même plutôt dangereux si on instance deux fois ta classe
  • le membre dbmd est instancié dans le constructeur mais tu ne l'utilises jamais : tu peux supprimer cette déclaration
  • la méthode statique affiche() est un renommage de System.out.println() (elle ne fait que ça) : le plus simple est de supprimer cette méthode et de remplacer chacun de ses appels par System.out.println(). En terme de refactoring on appelle cela l'inlining
  • ne jamais appeler System.exit() : on ne termine jamais un processus violemment comme ça (surtout vu ce que tu fais des connexions ouvertes vers ta base - j'en reparle plus bas).
  • une fois que tu as récupéré les données de chacune des lignes de ta requête tu ne nettoies rien : tu restes connecté à la base de données et ton ResultSet reste navigable. Si ta classe est instanciée très souvent, elle va finir par épuiser le stock de thread de connexions que ta base a alloué et finalement le programme Java va être bloqué. Pour clôturer proprement les ressources JDBC, il faut utiliser le mot clé finally de Java. Regarde ma proposition de solution plus bas pour voir comment ça peut fonctionner.
  • le mot de passe d'accès à ta base de données en clair dans le forum ce n'est pas très prudent : je te suggère de le supprimer dans ton post.


Si on se détache un peu de ton code : pour que les gens aient envie de t'aider, il faut que tu leur donnes plus d'informations sur l'erreur que tu rencontres. Le schéma de ta base de données aurait été un plus pour débugger. Par exemple voici le schéma que j'ai utilisé pour faire fonctionner ta classe :

Code :
  1. create table Question (Intitulé_Question varchar, Thème varchar, Bonne_Réponse integer, Réponse_1 varchar, Réponse_2 varchar, Réponse_3 varchar, Réponse_4 varchar);
  2. insert into Question values ('Quel président sera élu en 2012 ?', 'Politique', 4, 'Nicolas Sarkozy', 'François Hollande', 'Marine Le Pen', 'Obiwan Kenobi');


 
Proposition de solution :

Code :
  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.ResultSet;
  4. import java.sql.ResultSetMetaData;
  5. import java.sql.SQLException;
  6. import java.sql.Statement;
  7. import java.util.Vector;
  8. public class BaseDeDonneesOk {
  9.     private final Connection connexion_base;
  10.     private final Statement sql;
  11.     private final ResultSet table_questions;
  12.     public BaseDeDonneesOk() throws Exception {
  13.         // chargement du pilote
  14.         try {
  15.             Class.forName("org.postgresql.Driver" );
  16.         } catch (ClassNotFoundException e) {
  17.             System.err.println("Impossible de charger le pilote jdbc:odbc" );
  18.             throw e;
  19.         }
  20.         // connexion à la base de données
  21.         System.out.println("Connexion à la base de données en cours..." );
  22.         try {
  23.             connexion_base = DriverManager.getConnection("jdbc:postgresql://postgres-info/bdbaret", "userbaret", "******" );
  24.         } catch (SQLException e) {
  25.             System.err.println("Connexion à la base de données impossible" );
  26.             close();
  27.             throw e;
  28.         }
  29.         // création et exécution de la requete
  30.         System.out.println("Création et execution de la requête" );
  31.         String requete = "SELECT * FROM Question";
  32.         try {
  33.             sql = connexion_base.createStatement();
  34.             table_questions = sql.executeQuery(requete);
  35.         } catch (SQLException e) {
  36.             System.err.println("Anomalie lors de l'execution de la requête" );
  37.             close();
  38.             throw e;
  39.         }
  40.     }
  41.     public Vector<String[]> getListeQuestions() throws SQLException {
  42.         try {
  43.             ResultSetMetaData rsmd = table_questions.getMetaData();
  44.             int nbCols = rsmd.getColumnCount();
  45.             Vector<String[]> Vecteur = new Vector<String[]>();
  46.             String Tableau[] = new String[nbCols];
  47.             while (table_questions.next()) {
  48.                 for (int i = 0; i < nbCols; i++) {
  49.                     Tableau[i] = table_questions.getString(i + 1).toString();
  50.                 }
  51.                 Vecteur.add(Tableau);
  52.             }
  53.             return Vecteur;
  54.         } finally {
  55.             close();
  56.         }
  57.     }
  58.    
  59.     private void close() {
  60.         if (table_questions != null) {
  61.             try {
  62.                 table_questions.close();
  63.             } catch (SQLException e) {
  64.                 System.err.println(e.getMessage());
  65.             }
  66.         }
  67.         if (sql != null) {
  68.             try {
  69.                 sql.close();
  70.             } catch (SQLException e) {
  71.                 System.err.println(e.getMessage());
  72.             }
  73.         }
  74.         if (connexion_base != null) {
  75.             try {
  76.                 connexion_base.close();
  77.             } catch (SQLException e) {
  78.                 System.err.println(e.getMessage());
  79.             }
  80.         }
  81.     }
  82.     public static void main(final String[] args) throws Exception {
  83.         final BaseDeDonneesOk bd = new BaseDeDonneesOk();
  84.         for (final String[] donneesQuestion : bd.getListeQuestions()) {
  85.             final StringBuilder question = new StringBuilder();
  86.             question.append(donneesQuestion[1]).append(" : " ).append(donneesQuestion[0]).append('\n');
  87.             for (int i = 1; i <= 4; i++) {
  88.                 question.append(Integer.toString(i).equals(donneesQuestion[2])?'*':' ');
  89.                 question.append(' ').append(i).append(" - " ).append(donneesQuestion[i + 2]).append('\n');
  90.             }
  91.             question.append('\n');
  92.             System.out.println(question);
  93.         }
  94.         bd.close();
  95.     }
  96. }

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed