IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

methode d'interface inaccessible depuis classe metier!


Sujet :

avec Java

  1. #1
    Membre habitué Avatar de touftouf57
    Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 362
    Points : 174
    Points
    174
    Par défaut methode d'interface inaccessible depuis classe metier!
    Bonjour,

    je bosse sur un tp de gestion de machine.
    J'ai fait toute la partie métier.
    Maintenant j'attaque la partie connexion à la base.
    Pour cela je défini une interface

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    package baseDeDonnees;
    import java.sql.Connection;
    import java.sql.ResultSet;
     
    public interface AccesBaseDeDonnees {
    	public ResultSet lireDB(String rqtSQL);
    	public void ecrire(String SQL);
    	public void connecter();
    	public void deconnecter();
    }
    Dans la partie métier je souhaite lire des données dans la base
    mais je n'ai pas acces à la méthode lire(String rqtSQL). J'obtiens une erreur de compilation.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ResultSet rst=AccesBaseDeDonnees.lireDB("Select * From Marque");
    Eclipse me demande de modifier lireDB en static alors que dans l'interface il n'est autorisé que des public et/ou abstract.
    Vu que je ne sais pas comment sera implémenté AccesBaseDeDonnees,je pense qu'il est obligatoire de passer par l'interface pour accéder à la base de données.

    Donc pouvez-vous me dire ce que j'ai manqué?

    j'ai déjà créé une classe qui implémente accesBaseDeDonnees mais les méthodes sont vide, et cela ne résout en rien mon problème.

    Autre question:
    J'ai créer une classe BaseDeDonnées qui définit la base à "attaquer" et l'utilisateur. Elle se trouvee du coté métier, mais je me demande si elle ne devrait pas se trouver "de l'autre coté" vu quelle définit aussi le jdbc à utiliser pour attaquer la base.
    Je suppose que soit l'interface, soit la classe qui implémente l'interface doit étendre baseDeDonnees. je me trompe??

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    package baseDeDonnees;
     
    public class BaseDeDonnees {
    	private String host=new String();
    	private String port=new String();
    	private String nomBase = new String();
    	private String url=new String();
    	private Utilisateur user;
    	/**
             * @param host
             * @param port
             * @param nomBase
             * @param user
             */
    	public BaseDeDonnees(String host, String port, String nomBase,
    			Utilisateur user) {
    		this.host = host;
    		this.port = port;
    		this.nomBase = nomBase;
    		this.user = user;
    		init();
    	}
     
    	public BaseDeDonnees(String host, String port, String nomBase,
    			String nomUtilisateur, String password) {
    		this.host = host;
    		this.port = port;
    		this.nomBase = nomBase;
    		this.user = new Utilisateur(nomUtilisateur,password);
    		init();
    	}
    	/**
             * @equivaut à un setUrl mais avec les données de l'objet host,port et nom de la base;
             */
    	private void init(){
    		this.url = "jdbc:oracle:thin:@" + this.host + ":" + this.port+ ":" + this.nomBase;
    	}
    	/**
             * @return the host
             */
    	public String getHost() {
    		return host;
    	}
    	/**
             * @param host the host to set
             */
    	public void setHost(String host) {
    		this.host = host;
    	}
    	/**
             * @return the port
             */
    	public String getPort() {
    		return port;
    	}
    	/**
             * @param port the port to set
             */
    	public void setPort(String port) {
    		this.port = port;
    	}
    	/**
             * @return the nomBase
             */
    	public String getNomBase() {
    		return nomBase;
    	}
    	/**
             * @param nomBase the nomBase to set
             */
    	public void setNomBase(String nomBase) {
    		this.nomBase = nomBase;
    	}
    	/**
             * @return the user
             */
    	public Utilisateur getUser() {
    		return user;
    	}
    	/**
             * @param user the user to set
             */
    	public void setUser(Utilisateur user) {
    		this.user = user;
    	}
    	/**
             * @return the url
             */
    	public String getUrl() {
    		return url;
    	}
     
    }


    Merci d'avance

  2. #2
    Membre chevronné
    Avatar de CheryBen
    Inscrit en
    Mai 2005
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 599
    Points : 2 197
    Points
    2 197
    Par défaut
    Bonjour, on ne peut appeler des méthodes sur des classes que si elles sont déclarées static, or comme tu l'a vu, on ne peut pas mettre de static dans une interface.

    Tu dois donc créer une instance de la classe qui implémente AccesBaseDeDonnees et ensuite tu pourras appeler les méthodes de l'interface dessus.
    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    AccesBaseDeDonnees acces = new AccesBaseDeDonneesImpl();
    acces.lireDB("toto");
    Pour ta 2è question, pourquoi BaseDeDonnees n'implémenterai pas directement AccesBaseDeDonnees ?

  3. #3
    Membre habitué Avatar de touftouf57
    Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 362
    Points : 174
    Points
    174
    Par défaut
    Merci,

    En fait je souhaiterais faire une interface + une implémentation donc, qui si on change de base de données (pour l'instant c'est sur oracle, mais à l'avenir on pourrait passer sur MySQL), m'éviterais de "refactoriser" tout le code.

    CheryBen, tu me demandes pourquoi BaseDeDonnees n'implémenterait pas directement AccesBaseDeDonnees. Très bonne question, Je me le demandais hier soir.

    En fait, tu dois le savoir, pour attaquer une base de données il faut:
    • 1 driver (ici oracle.jdbc.driver.OracleDriver())
    • 1"urlDriver" (jdbc:oracle:thin)
    • 1 host (127.xxx.xxx.xxx)
    • 1 port
    • 1 nomBaseDeDonnees (baseOracle)
    • 1 utilisateur (nomUtilisateur + password)

    urlDriver + host + port + nomBaseDeDonnees l'url
    Driver + url + utilisateur connection
    Depuis hier soir je me triture le cerveau pour trouver un architecture qui:
    • contient toutes les données citées précédemment.
    • possède les méthodes d'AccesBaseDeDonnees.

    De tel façon que j'ai déjà une bonne partie du boulot de déjà fait concernant la connection à la base. Et que dans les implémentations je n'ai plus qu'a définir le Driver ainsi que les différentes requêtes SQL des méthodes qui seront appelées depuis le "métier" (LireMarque, LireMachine, InsereMarque...)

    Quel conseil me donnerais-tu pour que tout ceci soit le plus maniable et modulable possible?

    Encore merci
    (Tu dois me trouver un peu lourd tout de même.)

  4. #4
    Membre chevronné
    Avatar de CheryBen
    Inscrit en
    Mai 2005
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 599
    Points : 2 197
    Points
    2 197
    Par défaut
    En fait ce que tu cherches à faire (l'indépendance du serveur de base de données) est déjà offert par jdbc, c'est son principe même.

    Ce que tu devrais faire pour pouvoir changer de base de donnée à volonté en ayant une seule implémentation, c'est mettre les paramètres dans un fichier de configuration que tu peux charger facilement en utilisant la classe Properties.

    Globalement, si tu fais un fichier xml de configuration, tu as juste à appeler la méthode loadFromXML et ensuite getProperty pour récupérer les valeurs.

    Pour permettre de localiser le fichier de configuration, en général son chemin est donné en paramètre à l'application. (ou bien le chemin du répertoire dans lequel il se trouve)

    Avec sa, tu as une seule implémentation et la base de données peut-être modifiée à volonté sans recompilation.

    ps : visiblement tu te poses les bonnes questions donc ce n'est pas une corvée de te répondre, sinon je ne le ferai pas

  5. #5
    Membre habitué Avatar de touftouf57
    Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 362
    Points : 174
    Points
    174
    Par défaut
    Citation Envoyé par CheryBen Voir le message
    ps : visiblement tu te poses les bonnes questions donc ce n'est pas une corvée de te répondre, sinon je ne le ferai pas
    merci ça fait plaisir à lire

    Je vais essayé de faire un fichier de configuration XML.

    Maintenant je pense que je vais faire implementer AccesBaseDeDonnees par BaseDeDonnees. J'ai vu qu'il était possible de mettre des propriétés dans une interface mais comment y accéder?
    je reviens au même problème que hier. Je dois donc les mettre en attribut dans la classe qui implemente mon interface.
    Donc a quoi cela sert de mettre des attributs dans une interface?

    Je vais radoter "encore Merci" (une fois la trentaine passée on devient cénile )

  6. #6
    Membre chevronné
    Avatar de CheryBen
    Inscrit en
    Mai 2005
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 599
    Points : 2 197
    Points
    2 197
    Par défaut
    Les attributs dans les interfaces servent surtout à mettre des constantes static.

    Sinon tu as une autre solution, tu peux faire une classe abstraite qui implémente AccesBaseDeDonnees, sans en définir les méthodes, en y mettant les attributs que tu veux. Ainsi tu peux faire hériter BaseDeDonnees de la classe abstraite, et elle devra redéfinir les méthodes de l'interface.

  7. #7
    Membre habitué Avatar de touftouf57
    Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 362
    Points : 174
    Points
    174
    Par défaut
    Merci CheryBen,

    J'ai avancé (je n'avais pas vu ton conseil sur la classe abstraite, mais cela va être faisable et assez facilement). Quand je dis que j'ai avancé, c'est que j'ai fait toutes les méthodes de lecture de la base.
    J'ai 2 méthodes qui accède à la base pour l'instant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    	private ResultSet lireTableBDD(String rqtSQL) {
    		ResultSet rst = null;
    		try {
    			rst = this.connection.createStatement().executeQuery
                            (rqtSQL);
    		} catch (SQLException e) {
    			log.log(Level.WARNING, e.getMessage());
    		}
    		return rst;
    	}
     
    	private ResultSet lireBDD(String rqtSQL, String[] wildCard)
    			throws LectureBDDException {
    		ResultSet rst=null;
    		try {
    			PreparedStatement pst = this.connection.
                            prepareStatement(rqtSQL);
    			for (int i = 0; i < wildCard.length; i++)
    				pst.setObject(i + 1, wildCard[i]);
    			if (!pst.execute())
    				throw new LectureBDDException(
    				"La requete ne renvoi aucun résultat");
    			rst = pst.executeQuery();
                   } catch (SQLException e) {
    			log.log(Level.WARNING, e.getMessage());
    		}
    		return rst;
    	}
    Première question concernant if (!pst.execute()), je ne rentre jamais dans le throw new LectureBDDException alors que mes tables sont vides!!
    Je dois mal comprendre le preparedStatement.execute, n'est-il pas censé retourné false lorsque le premier "next" ne renvoi pas d'objet ResultSet?

    Ces 2 méthodes sont déclarées public puisque ceux sont les autres méthodes qui les appellent. voici un exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    	@Override
    	public DisqueDur lireDisqueDur(int idDisqueDur) throws LectureBDDException {
    		String[] wildCard = {String.valueOf(idDisqueDur) };
    		String rqtSQL="Select * From DISQUEDUR Where idDisqueDur = ?"; 
    		this.connecter();
    		ResultSet rst = lireBDD(rqtSQL,wildCard);
    		this.deconnecter();
    		return initDisqueDur(rst, 1);
    	}
     
    	@Override
    	public ArrayList<DisqueDur> lireDisqueDurMachine(int idMachine)
    			throws LectureBDDException, SQLException {
    		String[] wildCard = {String.valueOf(idMachine) };
    		String rqtSQL="Select * From DISQUEDUR Where idMachine = ?";
    		this.connecter();
    		ResultSet rst = lireBDD(rqtSQL,wildCard);
    		ArrayList<DisqueDur> aListDisqueDur=new ArrayList<DisqueDur>();
    		int i=0;
    		while(rst.next()){
    			i++;
    			aListDisqueDur.add(initDisqueDur(rst,i));
    		}
    		this.deconnecter();
    		return aListDisqueDur;
    	}
    toutes les autres méthodes ne sont que des copier-coller en modifiant la requête SQL et le type de retour. Donc 2° questions est-il possible d'en faire une générique
    J'ai voulu essayé de faire cette méthode mais sans succès (pardons pour le nom mais à 4h du mat l'inspiration n'était plus là )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	private ArrayList<T> lireXWhereYEgalIdZ(String nomTable, String nomChampsY, int idZ,Class classX){
    		String[] wildCard = { String.valueOf(idZ) };
    		ResultSet rst = lireBDD("select * from "+nomTable+" where "+idZ+" = ? ",
    				wildCard);
    		ArrayList<T> aList=new ArrayList<T>();
    		int i=0;
    		while(rst.next()){
    			i++;
    			aList.add(initObjet((T)classX.newInstance(),rst,i));
    		}
    		return aList;
    J'ai typé la classe en <T>, mais sur la méthode initObjet, Eclipse me demande de changer les types de paramètre en (T,ResultSet,int).

    Je voulais faire 1 initObjet pour chaque classe "metier" (j'en aurais eu une dizaine) , puisque c'est l'équivalent des constructeurs, mais en récupérant les données de la base.
    Vu que les données d'une classe ne sont pas forcément dans la même table, et que les champs de la base ne portent pas forcément les mêmes noms que leurs propriétés associées, je ne voyais pas de soucis à faire un initObjet avec comme premier paramètre le type de retour. par exemple:
    • private Parc initObjet(Parc parc, ResultSet rst, int index)
    • private Ecran initObjet(Ecran ecran, ResultSet rst, int index)

    de tes conseils avisés. @+

  8. #8
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 311
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 311
    Points : 9 526
    Points
    9 526
    Billets dans le blog
    1
    Par défaut
    Je me permets une remarque concernant ta méthode d'accès aux données.

    Il n'est pas conseillé de faire une classe centrale qui créée une connexion et renvoie des ResultSet, celui-ci étant directement lié à la connexion.
    Tu devrais te tourner vers le concept de DAO et de classe utilitaire pour les connexion, ci-joint un exemple simple

    (La classe utilitaire)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    package com.database;
     
    import java.sql.Connection;
    import java.sql.DriverManager;
     
    public class DataBaseUtils
    {
        public static Connection getConnection()
        {
            Connection connection = null;
            try
            {
                Class.forName("com.mysql.jdbc.Driver");
                connection = DriverManager.getConnection("jdbc:mysql://localhost/test", "user", "password");
                connection.setAutoCommit(false);
            }
            catch (Exception e)
            {
            }
            return connection;
        }
     
        public static void closeConection(Connection connection)
        {
            try
            {
                if (connection != null) connection.close();
            }
            catch (Exception e)
            {
     
            }
        }
    }
    (un exemple de DAO)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
     
    package com.database.dao;
     
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import com.database.DataBaseUtils;
    import com.database.entity.Person;
     
    public class PersonDAO
    {
        private static PersonDAO personDAO;
     
        private PersonDAO()    {}
     
        public static PersonDAO getInstance()
        {
            if (personDAO == null)
            {
                personDAO = new PersonDAO();
            }
            return personDAO;
        }
     
        public Integer addPerson(String firstName, String lastName, String address, String zip, String city) throws Exception
        {
            Connection connection = null;
            Integer uid = 0;
            try
            {
                connection = DataBaseUtils.getConnection();
     
                PreparedStatement pstmt = connection.prepareStatement("insert into T_PERSON(FIRST_NAME, LAST_NAME, ADDRESS, ZIP, CITY) values(?, ?, ?, ?, ?)");
                pstmt.setString(1, firstName);
                pstmt.setString(2, lastName);
                pstmt.setString(3, address);
                pstmt.setString(4, zip);
                pstmt.setString(5, city);
                pstmt.executeUpdate();
     
                connection.commit();
     
                ResultSet rs = pstmt.getGeneratedKeys();
                if(rs.next()) uid = rs.getInt(1);
            }
            catch (Exception e)
            {
                // logger
                throw e;
            }
            finally
            {
                DataBaseUtils.closeConection(connection);
            }
            return uid;
        }
     
        public Integer copyPerson(Integer uid, String prefix, String suffix) throws Exception
        {
            Connection connection = null;
            try
            {
                connection = DataBaseUtils.getConnection();
     
                PreparedStatement pstmt = connection.prepareStatement("select * from T_PERSON where UID=?");
                pstmt.setInt(1, uid);
                ResultSet rs = pstmt.executeQuery();
                if (rs.next())
                {
                    uid = addPerson(rs.getString("FIRST_NAME"), prefix+rs.getString("LAST_NAME")+suffix, rs.getString("ADDRESS"), rs.getString("ZIP"), rs.getString("CITY"));  
                }
            }
            catch (Exception e)
            {
                // logger
                throw e;
            }
            finally
            {
                DataBaseUtils.closeConection(connection);
            }
            return uid;
        }
     
        public void updatePerson(Person person) throws Exception
        {
            Connection connection = null;
            try
            {
                connection = DataBaseUtils.getConnection();
     
                PreparedStatement pstmt = connection.prepareStatement("update T_PERSON set FIRST_NAME=?, LAST_NAME=?, ADDRESS=?, ZIP=?, CITY=? where UID=?");
                pstmt.setString(1, person.getFirstName());
                pstmt.setString(2, person.getLastName());
                pstmt.setString(3, person.getAddress());
                pstmt.setString(4, person.getZip());
                pstmt.setString(5, person.getCity());
                pstmt.setInt(6, person.getUid());
                pstmt.executeUpdate();
     
                connection.commit();
            }
            catch (Exception e)
            {
                // logger
                throw e;
            }
            finally
            {
                DataBaseUtils.closeConection(connection);
            }
        }
     
        public void deletePerson(Integer uid) throws Exception
        {
            Connection connection = null;
            try
            {
                connection = DataBaseUtils.getConnection();
     
                PreparedStatement pstmt = connection.prepareStatement("delete from T_PERSON where UID = ?");
                pstmt.setInt(1, uid);
                pstmt.executeUpdate();
     
                connection.commit();
            }
            catch (Exception e)
            {
                // logger
                throw e;
            }
            finally
            {
                DataBaseUtils.closeConection(connection);
            }
        }
    }
    Et l'utilisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    PersonDAO.getInstance().updatePerson(person);
    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Points : 909
    Points
    909
    Par défaut
    Citation Envoyé par touftouf57 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    PreparedStatement pst = this.connection.prepareStatement(rqtSQL);
    [...]
    if (!pst.execute())
    	throw new LectureBDDException("La requete ne renvoi aucun résultat");
    rst = pst.executeQuery();
    Première question concernant if (!pst.execute()), je ne rentre jamais dans le throw new LectureBDDException alors que mes tables sont vides!!
    Je dois mal comprendre le preparedStatement.execute, n'est-il pas censé retourné false lorsque le premier "next" ne renvoi pas d'objet ResultSet?
    Je n'ai jamais utilisé la méthode execute, mais d'après la Javadoc cette méthode renvoie true si le premier résultat est un ResultSet (requête du type "SELECT"...), false s'il s'agit d'un nombre de mise à jour ("UPDATE", "DELETE", "INSERT"...) ou si aucun résultat n'est renvoyé (procédure stockée qui ne renvoit rien...)
    Dans ton cas il s'agit d'un SELECT, donc le premier (et seul ?) résultat est bien un ResultSet, donc execute te renverra true. Même si la table est vide : tu obtiendras tout bêtement un ResultSet vide...

    Le code à utiliser serait plutôt quelque chose de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    PreparedStatement pst = this.connection.prepareStatement(rqtSQL);
    [...]
    rst = pst.executeQuery();
    if (!rst.next())
    	throw new LectureBDDException("La requete ne renvoi aucun résultat");
    Par contre, attention pour les traitements suivants, là on a déjà avancé au premier résultat du ResultSet...

  10. #10
    Membre habitué Avatar de touftouf57
    Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 362
    Points : 174
    Points
    174
    Par défaut
    Merci OButterlin,

    Donc en utilisant le concept DAO, je devrais faire une classe "CRUD" pour chaque classe "métier", exact?

    Concernant la classe utilitaire, me conseilles-tu de faire comme l'exemple que tu as posté, (en version static au quel cas je rajouterais un paramètre BaseDeDonnnees) ou puis-je l'insérer directement dans ma classe BaseDeDonnees qui possède tous les attributs nécessaire à la connection?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    public class BaseDeDonnees {
    	private static Logger log = Logger.getLogger(BaseDeDonnees.class.getName());
    	private String nomDriver = new String();
    	private String urlDriver = new String();
    	private String host = new String();
    	private String port = new String();
    	private String nomBase = new String();
    	private String url = new String();
    	private Utilisateur user;
    	private Connection connection;
     
    	/**
             * @param nomFichierConfig
             * @param host
             * @param port
             * @param nomBase
             * @param user
             */
    	public BaseDeDonnees(String nomFichierConfig, String host, String port,
    			String nomBase, String nomUtilisateur, String password) {
    		ConfigBaseDeDonnees config = new ConfigBaseDeDonnees(nomFichierConfig);
    		try {
    			this.nomDriver=config.getPropriete("nomDriver");
                           this.urlDriver = config.getPropriete("urlDriver");
    			init(host, port, nomBase);
    			initUrl();
    			this.user = new Utilisateur(nomUtilisateur, password);
    		} catch (PropertieException e) {
    			e.printStackTrace();
    		}
     
    	}}
    Est-il pertinent d'avoir un attribut connection dans cette classe?

    Autre question: peux-tu me donner plus d'explications sur le getInstance()?
    pourquoi ne pas faire tout simplement un new?

    Merci.

  11. #11
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 311
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 311
    Points : 9 526
    Points
    9 526
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par touftouf57 Voir le message
    Donc en utilisant le concept DAO, je devrais faire une classe "CRUD" pour chaque classe "métier", exact?
    Oui, tout à fait, au moins une... la classe CRUD étant une DAO particulière (et particulièrement basique)...
    On peut imaginer avoir une DAO CRUD et n DAO de requêtes en fonction des besoins et faire de l'héritage également pour hiérarchiser le tout...
    Citation Envoyé par touftouf57 Voir le message
    Concernant la classe utilitaire, me conseilles-tu de faire comme l'exemple que tu as posté, (en version static au quel cas je rajouterais un paramètre BaseDeDonnnees) ou puis-je l'insérer directement dans ma classe BaseDeDonnees qui possède tous les attributs nécessaire à la connection?
    La classe utilitaire est typique d'une classe appelée partout, les paramètres de connexion sont plutôt inscrit dans un fichier de propriétés (pas dans une classe), ci-joint une version modifiée (le fichier de propriétés est à la racine et nommé DataBaseConnection.properties)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    package com.test;
     
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.util.ResourceBundle;
     
    public class DataBaseUtils
    {
        private static String driver;
        private static String url;
        private static String user;
        private static String password;
        static
        {
            ResourceBundle bundle = ResourceBundle.getBundle("DataBaseConnection");
            driver = bundle.getString("driver");
            url = bundle.getString("url");
            user = bundle.getString("user");
            password = bundle.getString("password");
        }
     
        public static Connection getConnection()
        {
            Connection connection = null;
            try
            {
                Class.forName(driver);
                connection = DriverManager.getConnection(url, user, password);
     
                connection.setAutoCommit(false);
            }
            catch (Exception e)
            {
                System.out.println(e.getMessage());
            }
            return connection;
        }
    }
    Citation Envoyé par touftouf57 Voir le message
    Est-il pertinent d'avoir un attribut connection dans cette classe?
    Non, la connexion ne devrait pas sortir de la méthode qui l'utilise...
    Citation Envoyé par touftouf57 Voir le message
    Autre question: peux-tu me donner plus d'explications sur le getInstance()?
    pourquoi ne pas faire tout simplement un new?
    Autre concept : singleton
    Là, tu garantis l'unicité de l'instance de l'objet en mémoire... auncun besoin d'en avoir plusieurs puisqu'elles feraient toutes la même chose, la seule partie variable étant les paramètres d'appel.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  12. #12
    Membre habitué Avatar de touftouf57
    Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 362
    Points : 174
    Points
    174
    Par défaut
    Merci, pour ces réponses.
    En ce qui concerne le fichier DataBaseConnection je préfèrerai passer par une classe, car une fois que j'aurais fini la "liaison" métier - base de données, je ferais aussi l'interface graphique.
    La seule obligation que j'ai pour l'interface graphique est que le premier panel doit être un panel d'identification, donc login + password, avec possibilité de choisir le nom de la base et la machine hôte. C'est pourquoi je mettais tourné vers la classe BaseDeDonnees. Par contre le fichier "DataBaseConnection" pourrais contenir les drivers du type de base utilisée. (ce que me conseillait CheryBen)
    Citation Envoyé par CheryBen
    En fait ce que tu cherches à faire (l'indépendance du serveur de base de données) est déjà offert par jdbc, c'est son principe même.

    Ce que tu devrais faire pour pouvoir changer de base de donnée à volonté en ayant une seule implémentation, c'est mettre les paramètres dans un fichier de configuration que tu peux charger facilement en utilisant la classe Properties.

    Globalement, si tu fais un fichier xml de configuration, tu as juste à appeler la méthode loadFromXML et ensuite getProperty pour récupérer les valeurs.

    Que veux-tu dire par là ?
    Citation Envoyé par OButterlin Voir le message
    Oui, tout à fait, au moins une... la classe CRUD étant une DAO particulière (et particulièrement basique)...
    Je n'ai pas saisi ça, et donc je ne vois pas comment le mettre en place?
    Citation Envoyé par OButterlin Voir le message
    On peut imaginer avoir une DAO CRUD et n DAO de requêtes en fonction des besoins et faire de l'héritage également pour hiérarchiser le tout...
    Voici l'interface que j'avais pensez (ok y a beaucoup de méthodes (je n'ai mis que ce qui concerne la lecture)). Comment puis-je appliquer la méthode DAO, tel que tu la décris?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    public interface AccesBaseDeDonnees {
    	// Lecture
    	public Marque lireMarque(int idMarque) throws LectureBDDException;
    	public ArrayList<Marque> lireTableMarque() throws LectureBDDException;
    	public Parc lireParc(int idParc) throws LectureBDDException;
    	public ArrayList<Parc> lireTableParc() throws LectureBDDException;
    	public Machine lireMachine(int idMachine) throws LectureBDDException;
    	public ArrayList<Machine> lireMachineParc(int idParc) throws LectureBDDException, SQLException;
    	public ArrayList<Machine> lireMachineSalle(int idSalle) throws LectureBDDException, SQLException;
    	public ArrayList<Machine> lireTableMachine() throws LectureBDDException;
    	public Processeur lireProcesseur(int idProcesseur) throws LectureBDDException;
    	public Processeur lireProcesseurMachine(int idMachine) throws LectureBDDException;
    	public ArrayList<Processeur> lireTableProcesseur() throws LectureBDDException;
    	public DisqueDur lireDisqueDur(int idDisqueDur) throws LectureBDDException;
    	public ArrayList<DisqueDur> lireDisqueDurMachine(int idMachine) throws LectureBDDException, SQLException;
    	public ArrayList<DisqueDur> lireTableDisqueDur() throws LectureBDDException;
    	public Ram lireRam(int idRam) throws LectureBDDException;
            public ArrayList<Ram> lireRamMachine(int idMachine) throws LectureBDDException, SQLException;
    	public ArrayList<Ram> lireTableRam() throws LectureBDDException;
    	public Ecran lireEcran(int idEcran) throws LectureBDDException;
    	public ArrayList<Ecran> lireEcranMachine(int idMachine) throws LectureBDDException, SQLException;
    	public ArrayList<Ecran> lireTableEcran() throws LectureBDDException;
    	public Intervention lireIntervention(int idIntervention) throws LectureBDDException;
    	public ArrayList<Intervention> lireInterventionMachine(int idMachine) throws LectureBDDException, SQLException;
    	public ArrayList<Intervention> lireTableIntervention() throws LectureBDDException;
    	public Lieu lireLieu(int idLieu) throws LectureBDDException;
    	public ArrayList<Lieu> lireTableLieu() throws LectureBDDException;
    	public Formation lireFormation(int idFormation) throws LectureBDDException;
    	public ArrayList<Formation> lireTableFormation() throws LectureBDDException;
    	public Salle lireSalle(int idSalle) throws LectureBDDException;
    	public ArrayList<Salle> lireSalleFormation(int idFormation) throws LectureBDDException, SQLException;
    	public ArrayList<Salle> lireSalleLieu(int idLieu) throws LectureBDDException, SQLException;
    	public ArrayList<Salle> lireTableSalle() throws LectureBDDException;
    Je crois avoir saisi maintenant (je dis bien "je crois"). Le CRUD DAO serait un CRUD "générique" et les n DAO utiliseraient ce CRUD?

    Je ne sais pas si j'arrive à me faire comprendre
    Merci @+

  13. #13
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 311
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 311
    Points : 9 526
    Points
    9 526
    Billets dans le blog
    1
    Par défaut
    Le CRUD est un DAO spécifique dans la mesure où elle s'occupe de l'accès et la persistance d'un "enregistrement" (pour simplifier, ça peut être plus complexe bien sûr).
    Généralement, dans une application, on accède aux données par différents critères de sélection qui peuvent dépendre du module concerné. Par contre, quand il s'agit de persister des modification (au sens large), c'est toujours identique (d'où le CRUD).
    Donc, pour l'aspect requêtes, on peut imaginer plusieurs DAO spécialisés (par module par exemple) qui étendent le CRUD (ou pas).

    Avec des technologies comme Hibernate, on peut effectivement faire un CRUD générique, mais avec JDBC, ce serait nettement plus compliqué puisque les requêtes vers les tables sont spécifiques à chaque fois.

    Sinon, ton interface me semble inutile, je dirais même qu'elle ne répond pas au concept... Elle semble plus définir un catalogue des méthodes qu'autre chose...
    L'interface permet de définir un "contrat", un voir plusieurs objets s'occupant de remplir un ou plusieurs contrats. Dans ton cas, elle mélange des choses très différentes (à priori) que seul un objet implémentera.
    Donc, la question est : A quoi va te servir ton interface ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  14. #14
    Membre habitué Avatar de touftouf57
    Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 362
    Points : 174
    Points
    174
    Par défaut
    OButterlin, bonjour

    Pour répondre à ta question, l'interface est censée accéder et modifier au données d'une base de données Oracle.

    Tu dis que mon interface ne répond pas au concept!!
    Donc vu les méthode que je dois utilisées sur ma base, que me conseillerais-tu de faire??

  15. #15
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 311
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 311
    Points : 9 526
    Points
    9 526
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par touftouf57 Voir le message
    Donc vu les méthode que je dois utilisées sur ma base, que me conseillerais-tu de faire??
    Pas d'interface, une classe qui implémente, c'est tout...

    Ceci dit, j'en ferais plusieurs, par spécialité... question de découpage...
    1 pour la base de données, 1 pour l'IHM, etc... Inspire-toi du modèle MVC, c'est bien pratique
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. classe applicative et classe metier ?
    Par sali dans le forum Diagrammes de Classes
    Réponses: 7
    Dernier message: 08/07/2009, 23h52
  2. Classe inaccessible depuis un projet Silverlight
    Par cyberbobby dans le forum Windows Communication Foundation
    Réponses: 6
    Dernier message: 25/05/2009, 15h33
  3. [EJB2] Accès Interface locale depuis une classe métier.
    Par rigor dans le forum Java EE
    Réponses: 2
    Dernier message: 10/10/2006, 14h44
  4. [DC] Modéliser une classe interface + une autre classe
    Par sangei dans le forum Diagrammes de Classes
    Réponses: 11
    Dernier message: 21/12/2005, 22h46
  5. Plesk Linux, Interface inaccessible
    Par thibaut06 dans le forum Débuter
    Réponses: 7
    Dernier message: 06/11/2005, 23h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo