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

JDBC Java Discussion :

[Framework] que des SELECT dans mon appli Web.


Sujet :

JDBC Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 20
    Points : 10
    Points
    10
    Par défaut [Framework] que des SELECT dans mon appli Web - idée de solution
    Bonjour à tous,

    je construis une appli web où 98% des requêtes seront des SELECT.
    En fait hormis l'inscription sur le site et la maj par batch la nuit, il n'y a aucun INSERT.
    La base est MySQL couplé à J2EE.

    Voilà ma question :
    Ai-je un intérêt à utiliser les EJB ? ou encore Hibernate ?

    Autre question :
    Existe t-il des framework 'light' pour ne faire que des select ? Si oui lesquels.

    Précision :
    En gros, ce que je recherche c'est un moteur de requêtes SQL écrit en java et qui éventuellement ferait du cache des résultats des requêtes et pouvant se connecter à un pool de connexion.

    Si quelqu'un a une piste, je suis preneur ... merci.
    UPDATE : J'ai finalement décider de faire quelque chose de mes petites mains, la suite, plus bas dans le topic. N'hésitez à faire des critiques constructives pour des optimisations ou encore pour me dire si des bouts de code ne sont pas jolis jolis

  2. #2
    Membre expérimenté
    Avatar de fabszn
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2002
    Messages
    974
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2002
    Messages : 974
    Points : 1 638
    Points
    1 638
    Par défaut
    Hello,

    L'interet d'utilliser des EJBs ne se resume pas uniquement à la nature des rêquêtes que tu vas écrire dans ton application.
    Les EJBs permettent de structurer ton application (Notion de service).

    Sinon, si tu à la possibilté de travailler avec la version 3.0 des EJBs (beaucoup plus simple et légère à mettre en ouvre).
    Le framework hibernate peut être une solution intéressante. Ce framework offre 2 niveaux de cache. 1 transactionnel (cache de niveau 1) et un autre de niveau 2 qui à un scope sur plusieurs transactions.
    Il te permettra d'etablir une bonne conception relationnelle de tes objets persistants.
    Deplus Hibernate possede des axes d'optimisations assez fin... et qui te permettra d'affiner tout cela!

    Concernant le framework light.... connait pas! Maintenant si tu n'as que des select à faire (ou quasiment) en architecturant convenablement ton applis tu devrais pouvoir arriver à un resultat plus que satisfaisant (en utilisant JDBC et un gestionnaire de pool).

    J'espère que cela t'aidera,Si tu as des questions n'hésite pas
    @+

    Fabszn
    Twitter : @fsznajderman

    N'oubliez pas le bouton
    Comment bien poser ses questions sur le forum


  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    salut fabszn,

    je vois très bien la notion des EJb, je comprends les services qu'ils rendent.
    Je ne crois pas que ce soit dans mon interet de les utiliser, en réalité, je n'ai pas réellement besoin de persistance. N'ayant que des select (ou presque), je me moque de conserver l'état d'un objet puisqu'il ne varie pas (si ce n'est par batch).

    Concernant Hibernate, la solution me plait, mais j'ai peur que le mécanisme offre trop de chose par rapport à mon besoin.
    C'est de là que vient l'idée de 'light'.

    Au final, je vais construire moi même le 'QueryManager', il ne fera que ce dont j'ai besoin, et je pourrais gérer le cache comme je le souhaite.
    Sans avoir l'intention de récreer la roue.
    En fait je pensais qu'il existait quelque chose comme ça ... avec le paramètrage des requêtes et du cache dans un xml.

    Si des gens sont interessés, je suis prêt à publier ma solution (d'ici quelques jours). Sans prétention, aucune.

  4. #4
    Membre expérimenté
    Avatar de fabszn
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2002
    Messages
    974
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2002
    Messages : 974
    Points : 1 638
    Points
    1 638
    Par défaut
    Hello,

    Je serai interessé par ta solution. C'est toujours intéressant et enrichissant.
    @+

    Fabszn
    Twitter : @fsznajderman

    N'oubliez pas le bouton
    Comment bien poser ses questions sur le forum


  5. #5
    Membre confirmé

    Inscrit en
    Avril 2005
    Messages
    317
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 317
    Points : 553
    Points
    553
    Par défaut
    il y a aussi DButils

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    Bien merci. Je ne vais pas utiliser DBUtils même si ca a l'air assez interessant.
    Je finalise mon code pour le week-end, et je le publierai.

    Par contre, je me posai une question sur les preparedStatement.
    Je la mets dans un topic dédié, là :
    http://www.developpez.net/forums/sho...d.php?t=180493

    UPDATE:
    La question est résolue.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    C'EST PARTI

    * Bien voilà j'arrive à un début de solution, je vais essayer de présenter les choses et le code java clairement.
    * Pour la compréhension la présentation se fera dans ce sens :
    1 - base de données
    2 - beans java associés
    3 - descripteur de requête (xml)
    4 - parser (Digester)
    5 - exécution des requêtes
    6 - mise en cache des beans

    * Pour l'exemple, je simplifie au maximum, la définition des objets, et je ne présente aucune gestion des exceptions.


    Base de données
    Une table SQL : USER (int id, Varchar2 name, TimeStamp date);

    Bean associée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    package bean;
     
    public class User {
     
      private int		id;
      private String		name;
      private Date		date;
     
      public User() {
      }
      // + les getters et setters qui vont bien
    }

    Descripteur de requêtes (xml)
    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
    <?xml version="1.0" encoding="UTF-8"?>
    <requestList>
    	<request>
    		<name>selectUserByName</name>
    		<queryType>SELECT</queryType>
    		<resultIsList>false</resultIsList>
    		<resultObjectType>bean.User</resultObjectType>
    		<result>id,name,date</result>
    		<query>FROM USER WHERE name=?</query>
    	</request>
     
    	<request>
    		<name>selectUserByDateInscription</name>
    		<queryType>SELECT</queryType>
    		<resultIsList>true</resultIsList>
    		<resultObjectType>bean.User</resultObjectType>
    		<result>id,name,date</result>
    		<query>FROM USER WHERE date=?</query>
    	</request>
     
    </requestList>
    Parser (Digester)
    Le xml n'étant pas compliqué, le digester ne le sera pas non plus.
    Le digester est un 'outil' de chez Jakarta pour le parsing xml.
    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
    public class DigesterRequests {
     
    	private static final String ROOT_TAG		= "requestList";
    	private	static final String REQUEST_TAG		= ROOT_TAG	+ "/request";
    	private	static final String NAME_TAG		= REQUEST_TAG	+ "/name";
    	private	static final String QUERY_TYPE_TAG	= REQUEST_TAG	+ "/queryType";
    	private	static final String RESULT_ISLIST_TAG	= REQUEST_TAG	+ "/resultIsList";
    	private	static final String RESULT_OBJECT_TYPE_TAG= REQUEST_TAG	+ "/resultObjectType";
    	private	static final String RESULT_TAG		= REQUEST_TAG	+ "/result";
    	private	static final String QUERY_TAG		= REQUEST_TAG	+ "/query";
     
    	private	static final String REQUEST_CREATION_METHOD	= "addRequestToList";
    	private	static final int	REQUEST_NB_FIELDS		= 6;
     
    	RequestList requestList;
     
    	public DigesterRequests() {
    		requestList = new RequestList();
    	}
     
    	public RequestList validerEtParserFichierXml(File xmlFile) throws Exception { 
     
    		Digester digester = new Digester();
    		digester.setValidating(true);
    		digester.push(this);
     
    		digester.addCallMethod(	REQUEST_TAG, REQUEST_CREATION_METHOD,	REQUEST_NB_FIELDS);
            		digester.addCallParam( 	NAME_TAG,				0 );
            		digester.addCallParam( 	QUERY_TYPE_TAG,				1 );
            		digester.addCallParam( 	RESULT_ISLIST_TAG,			2 );
            		digester.addCallParam( 	RESULT_OBJECT_TYPE_TAG,			3 );
            		digester.addCallParam( 	RESULT_TAG,				4 );
            		digester.addCallParam( 	QUERY_TAG,				5 );
     
     
    		try {
    			digester.parse(xmlFile);
    		} catch (IOException e) {
    			// TODO
    		} catch (SAXException e) {
    			// TODO
    		}
     
    		return requestList;
    	}
     
    	public void addRequestToList(String name, String queryType, String resultIsList, String resultObjectType, String result, String query) {
    		requestList.addRequest(new Request( name, queryType, resultIsList, resultObjectType, result, query));
    	}
     
    }
    Et les Classes Request et RequestList associées :
    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
    public class RequestList {
     
    	private HashMap map;
     
    	public RequestList() {
    		map = new HashMap();
    	}
     
    	public void addRequest(Request r) {
    		map.put( r.getName(), r);
    	}
     
    	public Request getRequest(String name) {
    		return (Request)map.get( name);
    	}
     
    	public Set keySet() {
    		return map.keySet();
    	}
    }
    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
    public class Request {
     
    	private	String		name;
    	private String		queryType;
    	private boolean		resultIsList;
    	private String		resultObjectType;
    	private String		query;
    	private String		result;
    	private ArrayList	resultList;
     
    	public Request(String name, String queryType, String resultIsList, String resultObjectType, String result, String query) {
     
    		this.name 				= name;
    		this.queryType 			= queryType;
    		this.resultObjectType 	= resultObjectType;
    		this.result 			= result;
    		this.query				= query;
     
    		if ( "TRUE".equals( resultIsList.toUpperCase()))
    			this.resultIsList = true;
    		else
    			this.resultIsList = false;
     
    		resultList = new ArrayList();
    		StringTokenizer st = new StringTokenizer(result, ",");
    		resultList.add( st.nextToken());
     
     
    	}
    	// + les getters qui vont bien
    }

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    SUITE

    Execution des requêtes
    Plusieurs choses sont à considérer pour la gestion des requêtes :
    * La classe doit être un singleton
    * La classe doit conserver les références à la datasource
    * La classe doit conserver les objets requête en mémoire
    * La classe ne possède qu'une seule méthode d'exécution de requête pour éviter les oublis de fermeture de connexion
    * Des sous méthodes privées peuvent être faites pour les différents type de requêtes

    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
    public class QueryManager {
    
    	// le singleton
    	private static QueryManager queryManager = new QueryManager();
    	
    	private DataSource 	ds;
    	private RequestList 	requests;
    
    	private QueryManager() {
    		// appelle du digester pour récupérer la liste des requetes
    		requests = (new DigesterRequests()).validerEtParserFichierXml( new File("requests.xml"));
    		
    		try {
    		// récupération de la Datasource
    		Context ic = new InitialContext();
    		Context envCtx = (Context) ic.lookup("java:comp/env");
    		ds = (DataSource) envCtx.lookup("jdbc/myDS");
    		
    		} catch (NamingException e) {
    			//TODO
    		}
    		
    	}
    	
    	// on récupère le singleton qui sera initiliasé une seule et unique fois
    	public static QueryManager getInstance() {
    		return queryManager;
    	}
    
    	// seule méthode d'exécution de requete
    	public ArrayList executeRequest(String requestName, Object[] params) {
    		
    		Request request = (Request)requests.getRequest(requestName);
    		
    		// on détermine le type de requête
    		if ("SELECT".equals( request.getQueryType().toUpperCase()))
    			return executeSelect( request, params);
    		else
    			//TODO
    	}
    	
    	// Exécution d'un select
    	private ArrayList executeSelect(Request request, Object[] params) {
    		
    
    		Connection 	cnx;
    		PreparedStatement 	ps;
    		ResultSet	rs;
    				
    		try {
    			cnx = ds.getConnection();
    			
    			// on contruit la requête
    			StringBuffer rqst = new StringBuffer("SELECT ").append(request.getResult()).append(" ").append(request.getQuery());
    						
    			ps = cnx.prepareStatement(rqst.toString());
    			for (int i=0; i<params.length; i++)
    				ps.setObject(i+1, params[i]);
    			
    			rs = ps.executeQuery();
    			
    			// on contruit la liste de retour qu'il n'y ait qu'un seul résultat ou plus
    			ArrayList beanList = new ArrayList();
    			Bean bean;
    			while (rs.next()) {
    				bean = (Bean)Class.forName(request.getResultObjectType()).newInstance();
    				bean.setValues( rs);
    				beanList.add(bean);
    			}
    			
    			rs.close();
    			ps.close();
    			cnx.close();
    
    			if ( beanList.size()== 0)
    				throw new Exception();
    
    			
    			return beanList;
    			
    		} catch (SQLException e) {
    			//TODO
    	    } catch (ClassNotFoundException e) {
    			//TODO
    	    } catch (InstantiationException e) {
    			//TODO
    	    } catch (IllegalAccessException e) {
    			//TODO
    	    }
    	}
    }
    Dans ce code une nouvelle classe est apparue. La classe Bean, c'est en fait une interface que doivent implémenter tous les beans.
    Une méthode abstraite est appelée sur cette interface, il faut donc l'implémenter dans tous les beans.
    Voici le code de l'interface, et la mise à jour du code de la classe Bean.user.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    package bean;
     
    public interface Bean {
    	public abstract void setValues(ResultSet rs) throws Exception;
    }
    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
    package bean;
     
    public class User {
     
      private int		id;
      private String		name;
      private Date		date;
     
      public User() {
      }
     
      public void setValues(ResultSet rs) throws Exception {
    	try {
    		this.id(		rs.getInt(1));
    		this.name(	rs.getString(2));
    		this.date( 	rs.getTimestamp(3));
    	} catch (SQLException e) {
    		// TODO
    	}
      // + les getters et setters qui vont bien
    }
    }

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    SUITE

    Mise en cache des beans
    Là aussi on passe par un singleton, on aura en fait un singleton par classe de bean.
    Il sera chargé de faire les appels aux requêtes concernant le bean.

    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 class UserManager {
    
    	private static UserManager userManager = new UserManager() ;
    
    	private HashMap users;
    
    	private UserManager() {
    		super();
    		users = new HashMap();
    	}
    
    	public static UserManager getInstance() {
    		return userManager;
    	}
    
    	public User getUser(String name) {
    		ArrayList list = QueryManager.getInstance().executeRequest("selectUserByName", new Object[] {name, pass});
    		User u = (User)list.get(0);
    		users.put(u.getIdKey(), u);
    		return u;
    	}
    
    	public User getUser(String idKey) throws Exception {
    		User u = (User) users.get(idKey);
    		if (u == null)
    			throw new Exception();
    
    		return u;
    	}
    
    	public void removeUserFromCache(String idKey) {
    		users.remove(idKey);
    	}
    }

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    SUITE
    Et le code d'appel à la requête, puis d'appel au bean mis en cache par la première execution de la requête.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    user = UserManager.getInstance().getUser("PIPO");
    System.out.println("je suis " + user.getName());
    System.out.println("id " + user.getId());
     
    System.out.println("---------------------------------------------------------------");
     
    user = UserManager.getInstance().getUser(id_qui_va_bien);
    System.out.println("je suis " + user.getName());
    System.out.println("id " + user.getId());

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    VOILA

    voilà l'idée, cela vous semble comment ?
    Je dois jeter de suite ?
    Sinon que faire pour améliorer ?

    Merci à ceux qui auront pris le temps de lire tout ça.

  12. #12
    Membre expérimenté
    Avatar de fabszn
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2002
    Messages
    974
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2002
    Messages : 974
    Points : 1 638
    Points
    1 638
    Par défaut
    Hello,

    Pour ma part je trouve ca très bien!

    Juste une petit question concernant les blocs synchronisés que tu utilises...
    Est ce que cela ne pose pas un verrou sur l'ensemble de la classe?
    @+

    Fabszn
    Twitter : @fsznajderman

    N'oubliez pas le bouton
    Comment bien poser ses questions sur le forum


  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    Salut fabszn,

    sur ce genre de méthode, tu veux dire ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static UserManager getInstance() {
    		if (userManager == null) {
    			synchronized (UserManager.class) {
    				if (userManager == null)
    					userManager = new UserManager();
    			}
    		}
    		return userManager;
    	}

    Non en fait tu ne synchronises que la création du singleton, l'appel au constructeur en fait.
    Pas besoin de synchroniser la classe ou la méthode getInstance().
    C'est fait comme cela pour éviter que le constructeur ne soit appelé plusieurs fois.

    Bien qu'apparemment IBM recommande plutot quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Singleton {
      private static Singleton instance = new Singleton();
     
      private Singleton() {
        //...
      }
     
      public static Singleton getInstance() {
        return instance;
      }
    }
    Pour plus d'info voir ce lien http://www-128.ibm.com/developerwork...dcl.html?loc=j

    UPDATE: Après lecture de la page http://christophej.developpez.com/tu...n/multithread/, il semble bel et bien préférable d'utilliser la seconde méthode.
    Je vais mettre à jour le code des classes, plus haut.

  14. #14
    Membre expérimenté
    Avatar de fabszn
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2002
    Messages
    974
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2002
    Messages : 974
    Points : 1 638
    Points
    1 638
    Par défaut
    Hello,

    Oui je connaissais le principe .. c'est une manière d'implémentation très rigoureuse et d'optimiser les acces concurrents.

    La question que je me posais c'etais par rapport à l'utilisation d'un bloc synchronized , plutot qu'une méthode synchronized comme ci dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
    public static UserManager getInstance() {
    		if (userManager == null) {
    	                   verifInstance();
        		}
    		return userManager;
    }
     
    private static synchronized void verifInstance(){
        if (userManager == null){
    		userManager = new UserManager();
        }
    }
    Voila je me posais cette question...
    @+

    Fabszn
    Twitter : @fsznajderman

    N'oubliez pas le bouton
    Comment bien poser ses questions sur le forum


  15. #15
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Je viens de jeter un coup d'oeil à ton code, et plus particulièrement la méthode executeSelect(). Je te conseillerais deux choses :
    • Utilises des blocs try/finally pour fermer proprement tes ressources quoi qu'il arrive. En effet dans ton code les méthodes close() ne sont jamais appellé en cas d'exception...
    • Fais remonter les exceptions par la méthode, afin de pouvoir renseigner la méthode appellante en cas d'erreur d'execution.
    Par 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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
        private ArrayList executeSelect(Request request, Object[] params)
        throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException {
     
            Connection cnx = ds.getConnection();
            try {
                // on contruit la requête
                StringBuffer rqst = new StringBuffer("SELECT ").append(
                        request.getResult()).append(" ").append(request.getQuery());
     
                PreparedStatement ps = cnx.prepareStatement(rqst.toString());
                try {
                    ResultSet rs = ps.executeQuery();
                    try {
     
                        // on contruit la liste de retour qu'il n'y ait qu'un seul résultat
                        // ou plus
                        ArrayList beanList = new ArrayList();
                        Bean bean;
                        while (rs.next()) {
                            bean = (Bean) Class.forName(request.getResultObjectType()).newInstance();
                            bean.setValues(rs);
                            beanList.add(bean);
                        }
     
                        if (beanList.size() == 0)
                            throw new SQLException();
                    } finally {
                        rs.close();
                    }
                } finally {
                    ps.close();
                }
     
            } finally {
                cnx.close();
            }
        }
    a++

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    salut adiGuba,

    UPDATE : adiGuda, gracias, il y a effectivement une petite erreur dans le code présenté. En fait si la requete ne retourne rien, je throw une exception et dans ce cas les connexions ne sont pas fermées. J'ai corrigé le code. Je clos simplement les connexions avant.

    merci pour les exceptions sur les connexions et requetes.
    Oui, ta façon de faire est très bien.
    J'ai implémenté ça différemment mais ca y ressemble beaucoup. En fait dans le code exposé ici, j'ai supprimé toute la gestion des exceptions de mon code original.

    Cependant, j'évite au maximum d'imbriquer des bloc try-catch les uns dans les autres car ça nuit aux performances. L'idée de ce mini-framework est de le faire le plus light et le plus performant possible.

    En fait, je préfère concentrer le topic sur la gestion des requêtes et des beans.
    Si vous avez des idées d'amélioration, ou si vous voyez un bug possible, faites m'en part, je ferai les maj nécessaire dans le code.

  17. #17
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    ReBonjour à tous,

    à ceux qui m'ont aidé pour ce topic merci.
    La version 0.2.0 de l'appli web est maintenant en place.
    Vous pouvez vous rendre compte du résultat, surtout si vous aimez ne serait ce que moyennement le foot.
    C'est un site de prono gratos (pas porno, lol) ...

    Voilà l'adresse :
    http://cosmopo.fr/

    Alors je fais peut-être un peu de pub, certes ...
    ... mais pas sans rien, je suis prêt à fournir de mon code, expliquer la façon dont je gère le système, répondre à vos questions ...

    Allez inscrivez vous !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Changer mon CSS dans mon appli web
    Par viladimitri dans le forum Développement Web en Java
    Réponses: 5
    Dernier message: 13/07/2011, 16h45
  2. utilisation des certificats dans mon site web
    Par ryodo dans le forum Sécurité
    Réponses: 1
    Dernier message: 09/04/2011, 21h45
  3. Réponses: 5
    Dernier message: 23/11/2010, 12h02
  4. [ghostscript] Portabilité de ghostscript dans mon appli WEB
    Par dacid dans le forum Shell et commandes GNU
    Réponses: 0
    Dernier message: 12/04/2010, 11h49
  5. Réponses: 3
    Dernier message: 03/04/2006, 18h30

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