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

Développement Web en Java Discussion :

Du mal à effectuer le lien entre DAO -> EntityManagerFactory -> jusqu'a la servlet


Sujet :

Développement Web en Java

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Septembre 2016
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Septembre 2016
    Messages : 52
    Points : 38
    Points
    38
    Par défaut Du mal à effectuer le lien entre DAO -> EntityManagerFactory -> jusqu'a la servlet
    Bonjour à tous, je sollicite fortement votre attention sur ce problème dans le cadre de préparation de mon examen pour le 10 septembre (très très important pour moi).

    Je vous remercie infiniment d'avance pour l'aide et l'attention que vous m'apporterez, n’hésitez pas à me demander plus amples informations.

    Le souçis est que mon professeur nous a donné 3 classes avec lesquels on doit se débrouiller mais j'ai vraiment du mal à comprendre où et comment faire le lien entre ces classes.

    Voiçi l'image de ce que contient mon projet actuellement:

    Nom : jv.gif
Affichages : 534
Taille : 542,5 Ko

    Résumer: J'ai créer un projet JSP, j'ai installer le serveur Tomcat, j'ai importer les librairies nécessaires que le prof nous a donné et j'ai pu générer avec JPA les Models qui sont la représentation de ce qu'il y a dans ma DB mysql. (j'ai donc configurer tous ce qu'il faut pour normalement avoir accès aux données de la DB).

    Voiçi donc les classes qui me posent souçis :

    La class "EMF" (qui se trouve dans un dossier qui s'appelle "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
    33
    34
    35
    36
     
     
    package com.og.connection;
     
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.Persistence;
     
    /** 
     * Class to get a connection to the database
     * 
     */
    public final class EMF {
     
    	private static EntityManagerFactory emfInstance =
    	        Persistence.createEntityManagerFactory("locationvoituresjsp");
     
        private EMF() {}
     
        public static EntityManagerFactory getEMF() {
            return emfInstance;
        }
     
        public static EntityManager getEM() {
            return emfInstance.createEntityManager();
        }
     
     /*	Create EntityManager in others classes
      * EntityManager em = EMF.get().createEntityManager();
      * try {
      *     // ... do stuff with em ...
      * } finally {
      *     em.close();
      * }
      */
    }
    La classe "EntityFinder" qui est une interface ainsi que la classe "EntityFinderlmpl" qui se trouvent tous les 2 dans le dossier "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
     
     
    package com.og.dao;
     
    import java.util.List;
    import java.util.Map;
     
    import javax.persistence.EntityManager;
     
    /**
     * 
     * 
     */
    public interface EntityFinder<T> {
     
    	/**      
             * Interface method to find an entity from the database
             *       
             * @param <T>
             *          Generic backing bean
             * @param Object
             *          Backing bean's id to find
             *                   
             * @return 
             *                      Generic backing bean
             */	
    	public T findOne(T t, int id);
     
    	/**      
             * Interface method to find a result of entities based on a NamedQuery from the database
             *       
             * @param String
             *          The NamedQuery          
             * @param <T>
             *          Generic backing bean
             * @param param
             *          Query parameters
             *          For Date params, key must contains the word(ci) 'date'
             *
             * @return 
             *                      List of generic backing beans
             */	
    	public <K, V> List<T> findByNamedQuery(String namedQuery, T t, Map<K, V> param);
     
    	/**      
             * Interface method to find a result of entities based on a customQuery from the database
             *       
             * @param String
             *          The customQuery          
             * @param <T>
             *          Generic backing bean
             * @param param
             *          Query parameters
             *          For Date params, key must contains the word(ci) 'date'
             *          
             * @return 
             *                      List of generic backing beans
             */	
    	public <K, V> List<T> findByCustomQuery(String customQuery, T t, Map<K, V> param);	
    }
    et voiçi le EntityFinderlmpl :

    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
     
     
    package com.og.dao;
     
    import java.io.Serializable;
    import java.util.*;
    import javax.inject.Inject;
    import javax.persistence.EntityManager;
    import javax.persistence.Query;
    import javax.persistence.TemporalType;
     
    import org.apache.log4j.Logger;
     
    import com.og.connection.EMF;
     
    /** 
     * Class to perform entity CRUD with the database
     * 
     */
    public class EntityFinderImpl<T> implements EntityFinder<T>, Serializable {
     
    	private static final long serialVersionUID = 1L;
     
    	/**
         * Default constructor
         */
    	public EntityFinderImpl(){
    		super();
    	}
     
    	// Log4j	 
    	@Inject
    	private transient Logger log;
     
    	@Override
    	public T findOne(T t, int id) {
     
    		EntityManager em = EMF.getEM();		
    		Class<? extends Object> ec = t.getClass();
    		try {
     
    	    	t = (T)em.find(ec, id);
     
    	    	em.clear();
     
    	    	log.debug("Bean " + t + " find from database: Ok");
    	    } finally {
    	        em.close();
    	        log.debug("Close em : Ok");
    	    }
     
    		return t;
    	}
     
    	@Override
    	public <K, V> List<T> findByNamedQuery(String namedQuery, T t, Map<K, V> param) {
     
    		List<T> listT = new ArrayList<T>();
    		Class<? extends Object> ec = t.getClass();
     
    		EntityManager em = EMF.getEM();
    		try {
    		    Query query = em.createNamedQuery(namedQuery, ec);
     
    	    	if(param != null) {
     
    	    		setParameters(query, param);		
    	    	}
    	    	listT = (List<T>) query.getResultList();
     
    	    	log.debug("List " + t + " size: " + listT.size());       
    	    	log.debug("Named query " + namedQuery + " find from database: Ok");	    
    		}
    		finally {
     
    			em.clear();
    	        em.close();
    	    }
    		return listT;
    	}
     
    	@Override
    	public <K, V> List<T> findByCustomQuery(String customQuery, T t, Map<K, V> param) {
     
    		List<T> listT = new ArrayList<T>();
    		Class<? extends Object> ec = t.getClass();
     
    		EntityManager em = EMF.getEM();
    		try {
    	    	Query query = em.createQuery(customQuery, ec);
    	    	if(param != null) {
     
    	    		setParameters(query, param);
    	    	}
    	    	listT = (List<T>) query.getResultList();
     
    	    	log.debug("List " + t + " size: " + listT.size());       
    	    	log.debug("Custom query " + customQuery + " find from database: Ok");
    		}
    		finally {
     
    			em.clear();
    	        em.close();
    	    }
    		return listT;
    	}
     
    	/**  
             * @param query
             * @param param
             * @return
             *                      the query with parameters
             */
    	private <K, V> void setParameters(Query query, Map<K, V> param) {
     
    		Set<Map.Entry<K, V>> entries = param.entrySet();
    		Iterator<Map.Entry<K, V>> itr = entries.iterator();
    		while(itr.hasNext()){
    			Map.Entry<K, V> entry = itr.next();
    			if((boolean) entry.getKey().toString().toLowerCase().contains("date"))
    				query.setParameter((String) entry.getKey(),(Date) entry.getValue(), TemporalType.DATE);
    			else
    				query.setParameter((String) entry.getKey(),entry.getValue());
    			//log.debug("entry.getValue: " + entry.getValue());
    		}
    	}
     
    }
    Alors je comprend vaguement à quoi servent les classes. Une permet la connection à la DB et une autre permet la récupération des objets qui se trouvent dans ma DB.

    J'ai donc créer une servlet ainsi qu'une vue pour préparer mes tests, mais je bloque... Je ne sais pas à quel endroit exactement ni comment organiser tous ça de manière à pouvoir renvoyer simplement un Objet de ma DB à ma vue. En sachant qu'il faut prendre en compte la persistance des données. Alors je pensais au début appeler toutes ces classes que mon prof m'a donné dans la méthode doPost() de la servlet que j'ai créer pour les test mais je ne suis pas sûr de la bonne pratique

    J'espère que tous ceci parlera facilement à quelqu'un, car je suis un peu perdu. Je vous remercie encore de l'attention que vous apporterez. Un exemple de comment je pourrais faire le lien entre tous ça je pense m'aiderai énormément pour l'implémenter dans ma méthode doPost(); (si c'est le bon endroit)

    Merci encore à vous, c'est très très important pour moi COMPRENDRE et ainsi réussir mon examen.

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par sali6000 Voir le message

    Alors je comprend vaguement à quoi servent les classes. Une permet la connection à la DB et une autre permet la récupération des objets qui se trouvent dans ma DB.

    Alors le EntityManagerFactory n'a pas de connexion à la DB, il a juste une représentation de ton modèle de données JPA ainsi que des informations sur comment il pourrait se connecter à la DB et créer des transaction

    Le EntityManager, qui sort de EntityManagerFactory.createEntityManager(), lui, il a une connexion à la DB, éventuellement une transaction en cours suivant comment est configuré ton JPA, et c'est lui que tu utilisera pour manipuler tes données (Select, Create, Update, Delete)

    Les classes EntityFinder sont une forme d'abstraction spécifique à ton code mais assez courrament utilisé, qui permet d'abstraire en gros la complexité et présenter des méthode simple (récupérer X, faire des recherches, etc). Cette interface dans ce cas si est un peu mal branlée dans le sens où elle te demande une entité pour te retourner une entité, alors qu'elle ne peux de toutes façon travailler qu'avec un type T. Elle pourrait être vachement refaite mieux, mais si j'ai bien compris tu dosi la garder telle quelle, ton prof pensant savoir ce qu'il fait
    En plus, l'entity manager a une durée de vie très courte dans cette interface alors qu'il vaut mieux garder le même entitymanager pour toutes tes opérations faites dans la même requêtes HTTP, sinon c'est galère intégrale pour mettre à jour des objets et ça va tuer la DB coté performances à faire 36.000 négociations au lieu d'une:/

    Citation Envoyé par sali6000 Voir le message
    Je ne sais pas à quel endroit exactement ni comment organiser tous ça de manière à pouvoir renvoyer simplement un Objet de ma DB à ma vue.
    Ta question est spécifique à ton objet DB ou simplement tu ne vois pas comment filer un objet quelconque à une JSP (j'assume que ta vue est en jsp)?

    Citation Envoyé par sali6000 Voir le message
    Alors je pensais au début appeler toutes ces classes que mon prof m'a donné dans la méthode doPost() de la servlet que j'ai créer pour les test mais je ne suis pas sûr de la bonne pratique
    Pourquoi tu ne nous filerais pas le code que t'as créée qu'on jette un oeil?

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Septembre 2016
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Septembre 2016
    Messages : 52
    Points : 38
    Points
    38
    Par défaut
    Merci pour tes informations, ça semblera plus compliqué que prévu apparemment d'après ce que tu dis

    Quel code souhaite tu avoir ? Voiçi mon github avec mon projet complet sinon : https://github.com/sali6000/JSP-MVC/

    Pour l'instant j'ai générer tous mes models avec JPA donc voiçi 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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
     
    package model;
     
    import java.io.Serializable;
    import javax.persistence.*;
     
     
    /**
     * The persistent class for the employer database table.
     * 
     */
    @Entity
    @NamedQuery(name="Employer.findAll", query="SELECT e FROM Employer e")
    public class Employer implements Serializable {
    	private static final long serialVersionUID = 1L;
     
    	@Id
    	@GeneratedValue(strategy=GenerationType.IDENTITY)
    	private int identifiant;
     
    	private String type_de_contrat;
     
    	public Employer() {
    	}
     
    	public int getIdentifiant() {
    		return this.identifiant;
    	}
     
    	public void setIdentifiant(int identifiant) {
    		this.identifiant = identifiant;
    	}
     
    	public String getType_de_contrat() {
    		return this.type_de_contrat;
    	}
     
    	public void setType_de_contrat(String type_de_contrat) {
    		this.type_de_contrat = type_de_contrat;
    	}
     
    }

    Voiçi le servlet qui me sert de test :

    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
    package com.servlets;
     
    import java.io.IOException;
    import java.io.PrintWriter;
     
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    /**
     * Servlet implementation class Reservation
     */
    @WebServlet("/Reservation")
    public class Reservation extends HttpServlet {
    	private static final long serialVersionUID = 1L;
     
        /**
         * @see HttpServlet#HttpServlet()
         */
        public Reservation() {
            super();
            // TODO Auto-generated constructor stub
        }
     
    	/**
             * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
             */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		String test = "mon message";
    		request.setAttribute("mon test :", test);
    		this.getServletContext().getRequestDispatcher( "/WEB-INF/ReservationView.jsp" ).forward( request, response );
    	}
     
    	/**
             * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
             */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		doGet(request, response);
    	}
     
    }
    et voiçi ma vue actuellement qui a été créée en JSP. J'arrive donc à bien renvoyé la vue que je souhaite en fonction du servlet que j'utilise.

    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
     
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
    hejjj
     
    <p>
    <% out.println((String) request.getAttribute("test")); %>
    </p>
     
    </body>
    </html>
    Le plus dur pour moi sera vraiment de comprendre comment je peut récupérer les objets de ma DB avec les class que le prof nous a donné, sinon coté Servlet et JSP je pense pouvoir gérer ça. Ne faites pas attention aux codes dans ma servlet et ma vue JSP car je sais que ce n'est pas la bonne pratique, c'était juste pour comprendre un peu le mécanisme coté servlet et JSP.

    Donc pour l'instant je n'ai que ça comme code:

    - Les 3 classes que mon prof nous a donné et que j'ai montré plus haut relatif aux requêtes sur ma DB
    - Les models
    - Une servlet qui s'occupera de gérer le Model dont j'ai besoin (une seul pour l'instant car j'aimerais réussir à implémenter les 3 classes du prof pour commencer)
    - Une vue qui me permettra d'afficher le Model dont j'ai besoin

    N'hésite pas à me demander si tu souhaite avoir un code spécifique et j'espère que tu as su voir mon image plus haut qui montre les classes que j'ai dans mon projet (le petit GIF animé).

    PS: Oui j'aimerais renvoyé un objet quelconque de ma DB à ma vue. Ce serais la clé qui résoudrais le problème principal.

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 462
    Points : 896
    Points
    896
    Billets dans le blog
    5
    Par défaut
    Tu utilises ce que l'on appelle un modèle en couche.

    Tu as deux couches: Le contrôleur et la DAO.
    Le principe est le même que le modèle OSI en réseaux (https://fr.wikipedia.org/wiki/Mod%C3%A8le_OSI)

    La couche contrôleur est la Servlet.

    La DAO sert à intéragir avec la BDD. Ici, c'est l'ORM (Object Relationnal Mapping) Hibernate qui est utilisé.

    L'intérêt de faire ça est de vraiment découpler le traitement de la requête, l'accès en BDD ..., de faire des briques et de faire un code plus lisible et maintenable.

    C'est plus facile de remplacer une brique que de remplacer un code lourd faisant plusieurs choses.

    Dans ton cas, il suffit d'injecter la DAO dans la Servlet.

    La manière la plus simple est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EntityFinder<Employer> ef = new EmployerFinder()
    Tu remarqueras que la DAO doit être declare par son interface. Après tout, la DAO est un contrat, et on manipule un contrat. Comme ça, on peut changer l'implémentation. Le contrat reste le meme, et du coup, seul la ligne de code donnée change. Le reste du code reste le meme.

    Le deuxième point est que tu as un Template Method (c'est un Design Pattern https://fr.wikipedia.org/wiki/Patron_de_m%C3%A9thode )
    L'objectif est de factoriser du code.
    En l'occurence, dans ton cas, c'est la classe EntityFinderImpl.

    Il est aussi tout simplement possible d'ailleurs d'injecter comme ça pour ton cas particulier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EntityFinder<Employer> ef = new EntityFinderImpl<Employer>()
    Néanmoins, en général, le Template Method est une classe abstraite (et en general, il y a de bonnes raisons de le faire).

    Si tu optes pour la classe EmployerFinder, EmployerFinder héritera du Template Method.


    Enfin, sache qu'en general, il y a des subtilités.
    En géneral, on veut une seule implementation de la DAO, qui de fait devient un Singleton.

    Néanmoins, dans la pratique, dans l'industrie, on ne fait pas comme ça.

    L'injection de dépendances se fait par un moteur d'injection de dependence, en l'occurence CDI ou, le plus connu, Spring.

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Septembre 2016
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Septembre 2016
    Messages : 52
    Points : 38
    Points
    38
    Par défaut
    Merci pour ta réponse.

    J'ai finalement réussi mon examen.

    J'ai pour ça fait comme tu as dis c'est à dire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    EntityManager<Employe> serviceEmploye = new EntityManager<Employe>;
    Employe employe = serviceEmploye.Find(24);
    EntityManager implémente EntityManagerFactory

  6. #6
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 462
    Points : 896
    Points
    896
    Billets dans le blog
    5
    Par défaut
    Il n'y a pas de quoi.

Discussions similaires

  1. Lien entre JSP et DAO Distante
    Par kayri dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 13/03/2013, 13h42
  2. Réponses: 5
    Dernier message: 06/10/2011, 14h43
  3. Lien entre un formulaire et un recordset DAO
    Par MrPiMs dans le forum VBA Access
    Réponses: 4
    Dernier message: 13/04/2011, 17h48
  4. [Framework] faire le lien entre le DAO et la jsp
    Par etudiantinformatik dans le forum Spring
    Réponses: 1
    Dernier message: 21/03/2011, 18h11
  5. [DAO] Faire le lien entre les VO et les Objets Métiers
    Par mauvais_karma dans le forum Hibernate
    Réponses: 12
    Dernier message: 25/11/2005, 15h19

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