Tutoriel d'exemple de source de données JNDI Tomcat Hibernate

De Get Docs
Aller à :navigation, rechercher

Bienvenue dans le didacticiel d'exemple Hibernate Tomcat JNDI DataSource. Nous avons déjà vu comment utiliser l'outil Hibernate ORM dans une application autonome java , aujourd'hui nous allons apprendre à utiliser Hibernate avec DataSource dans le conteneur de servlet Tomcat. L'utilisation de l'hibernation dans l'application Web est très simple, tout ce dont nous avons besoin est de configurer DataSource properties dans le fichier de configuration d'hibernation. Tout d'abord, nous devons configurer la base de données de test et JNDI DataSource dans le conteneur Tomcat.

Exemple de configuration de base de données Hibernate DataSource JNDI

J'utilise MySQL pour mon exemple, le script ci-dessous est exécuté pour créer une table simple et y insérer des valeurs. employee.sql

CREATE TABLE `Employee` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `role` varchar(20) DEFAULT NULL,
  `insert_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8;

INSERT INTO `Employee` (`id`, `name`, `role`, `insert_time`)
VALUES
    (3, 'Pankaj', 'CEO', now());
INSERT INTO `Employee` (`id`, `name`, `role`, `insert_time`)
VALUES
    (14, 'David', 'Developer', now());

Le nom du schéma de la base de données est TestDB.

Configuration de la source de données Tomcat JNDI

Pour configurer le conteneur tomcat pour initialiser DataSource, nous devons apporter quelques modifications aux fichiers tomcat server.xml et context.xml. server.xml

<Resource name="jdbc/MyLocalDB" 
      global="jdbc/MyLocalDB" 
      auth="Container" 
      type="javax.sql.DataSource" 
      driverClassName="com.mysql.jdbc.Driver" 
      url="jdbc:mysql://localhost:3306/TestDB" 
      username="pankaj" 
      password="pankaj123" 
      
      maxActive="100" 
      maxIdle="20" 
      minIdle="5" 
      maxWait="10000"/>

Ajouter la ressource ci-dessus dans le server.xml GlobalNamingResources élément. context.xml

<ResourceLink name="jdbc/MyLocalDB"
              global="jdbc/MyLocalDB"
              auth="Container"
              type="javax.sql.DataSource" />

Ajouter ci-dessus ResourceLink dans le fichier context.xml, il est nécessaire pour que les applications puissent accéder à la ressource JNDI avec le nom jdbc/MyLocalDB. Redémarrez simplement le serveur, vous ne devriez voir aucune erreur dans les journaux du serveur tomcat. S'il y a des configurations incorrectes, comme un mot de passe erroné, vous obtiendrez l'exception correspondante dans le journal du serveur. Vous devez également vous assurer que le fichier jar du pilote MySQL se trouve dans le répertoire tomcat lib, sinon tomcat ne pourra pas créer de connexion à la base de données et vous obtiendrez ClassNotFoundException dans les journaux. Maintenant que la configuration JNDI de notre base de données et de notre serveur Tomcat est prête, passons à la création de notre application Web à l'aide de la mise en veille prolongée.

Exemple de projet Web dynamique Hibernate DataSource

Créez un projet Web dynamique dans Eclipse, puis configurez-le en tant que projet Maven. La structure de notre projet final ressemblera à l'image ci-dessous. Notez que j'utilise Tomcat-7 pour le déploiement de mon projet et que je l'ai ajouté au chemin de construction, de sorte que nous n'avons pas besoin d'ajouter séparément les dépendances de l'API Servlet dans notre projet. Tomcat-7 prend en charge Servlet 3 specs et nous utiliserons des annotations pour créer nos servlets. Si vous n'êtes pas familier avec les annotations du servlet 3, vous devriez consulter le Tutoriel du servlet pour les débutants. Examinons chacun des composants un par un.

Hibernate Maven Dépendances

Notre fichier pom.xml final ressemble à ci-dessous.

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>HibernateDataSource</groupId>
    <artifactId>HibernateDataSource</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    
    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.5.Final</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.0.5</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <warSourceDirectory>WebContent</warSourceDirectory>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
        <finalName>${project.artifactId}</finalName>
    </build>
</project>

J'utilise la dernière version d'Hibernate 4.3.5.Final, hibernate-core la dépendance est ajoutée pour Hibernate. mysql-connector-java La dépendance est ajoutée car nous utilisons la base de données MySQL, bien que la portée soit fournie car elle fait déjà partie des bibliothèques de conteneurs Tomcat. Même si nous n'ajoutons pas de dépendances au pilote MySQL, notre projet se compilera et fonctionnera correctement. Cependant, il est préférable de l'inclure afin que si quelqu'un examine les dépendances du projet, il sera clair que nous utilisons la base de données MySQL.

Configuration de la source de données Hibernate

Notre fichier de configuration d'hibernation avec la source de données ressemble à ci-dessous. hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.datasource">java:comp/env/jdbc/MyLocalDB</property>
        <property name="hibernate.current_session_context_class">thread</property>
        
        <!-- Mapping with model class containing annotations -->
    <mapping class="com.journaldev.servlet.hibernate.model.Employee"/>
    </session-factory>
</hibernate-configuration>

hibernate.connection.datasource La propriété est utilisée pour fournir le nom DataSource qui sera utilisé par Hibernate pour les opérations de base de données.

Classe de modèle d'exemple de source de données Hibernate

Comme vous pouvez le voir dans le fichier de configuration d'hibernation, nous utilisons des annotations dans notre classe de modèle Employee. Notre modèle bean ressemble à ci-dessous. Employee.java

package com.journaldev.servlet.hibernate.model;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Entity
@Table(name="Employee", 
       uniqueConstraints={@UniqueConstraint(columnNames={"ID"})})
public class Employee {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="ID", nullable=false, unique=true, length=11)
    private int id;
    
    @Column(name="NAME", length=20, nullable=true)
    private String name;
    
    @Column(name="ROLE", length=20, nullable=true)
    private String role;
    
    @Column(name="insert_time", nullable=true)
    private Date insertTime;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getRole() {
        return role;
    }
    public void setRole(String role) {
        this.role = role;
    }
    public Date getInsertTime() {
        return insertTime;
    }
    public void setInsertTime(Date insertTime) {
        this.insertTime = insertTime;
    }
}

Le modèle bean est le même que celui que nous avons utilisé dans Hibernate Beginners Tutorial , vous devriez le vérifier si vous avez une confusion liée à l'une des annotations utilisées.

Hibernate DataSource Tomcat JNDI Écouteur de servlet

Puisque nous devons initialiser Hibernate SessionFactory parce que nous pouvons l'utiliser dans l'application et aussi lorsque l'application Web est détruite, nous devons détruire SessionFactory. Donc, le meilleur endroit pour le faire dans un ServletContextListener la mise en oeuvre. HibernateSessionFactoryListener.java

package com.journaldev.servlet.hibernate.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.jboss.logging.Logger;

@WebListener
public class HibernateSessionFactoryListener implements ServletContextListener {

    public final Logger logger = Logger.getLogger(HibernateSessionFactoryListener.class);
    
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        SessionFactory sessionFactory = (SessionFactory) servletContextEvent.getServletContext().getAttribute("SessionFactory");
        if(sessionFactory != null && !sessionFactory.isClosed()){
            logger.info("Closing sessionFactory");
            sessionFactory.close();
        }
        logger.info("Released Hibernate sessionFactory resource");
    }

    public void contextInitialized(ServletContextEvent servletContextEvent) {
        Configuration configuration = new Configuration();
        configuration.configure("hibernate.cfg.xml");
        logger.info("Hibernate Configuration created successfully");
        
        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
        logger.info("ServiceRegistry created successfully");
        SessionFactory sessionFactory = configuration
                .buildSessionFactory(serviceRegistry);
        logger.info("SessionFactory created successfully");
        
        servletContextEvent.getServletContext().setAttribute("SessionFactory", sessionFactory);
        logger.info("Hibernate SessionFactory Configured successfully");
    }
    
}

Si vous n'êtes pas familier avec les écouteurs de servlet, veuillez lire Tutoriel d'écoute de servlet.

Hibernate Tomcat JNDI Exemple d'implémentation de servlet

Écrivons un servlet simple où nous transmettrons l'identifiant de l'employé en tant que paramètre de requête et il imprimera les informations sur l'employé à partir de la base de données, évidemment nous utiliserons Hibernate pour interroger la base de données et obtenir des informations sur l'employé. GetEmployeeByID.java

package com.journaldev.servlet.hibernate;

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;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.jboss.logging.Logger;

import com.journaldev.servlet.hibernate.model.Employee;

@WebServlet("/GetEmployeeByID")
public class GetEmployeeByID extends HttpServlet {
    private static final long serialVersionUID = 1L;
    
    public final Logger logger = Logger.getLogger(GetEmployeeByID.class);
       
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int empId = Integer.parseInt(request.getParameter("empId"));
        logger.info("Request Param empId="+empId);
        
        SessionFactory sessionFactory = (SessionFactory) request.getServletContext().getAttribute("SessionFactory");
        
        Session session = sessionFactory.getCurrentSession();
        Transaction tx = session.beginTransaction();
        Employee emp = (Employee) session.get(Employee.class, empId);
        tx.commit();
        PrintWriter out = response.getWriter();
        response.setContentType("text/html");
        if(emp != null){
        out.print("<html><body><h2>Employee Details</h2>");
        out.print("<table border=\"1\" cellspacing=10 cellpadding=5>");
        out.print("<th>Employee ID</th>");
        out.print("<th>Employee Name</th>");
        out.print("<th>Employee Role</th>");
        
            out.print("<tr>");
            out.print("<td>" + empId + "</td>");
            out.print("<td>" + emp.getName() + "</td>");
            out.print("<td>" + emp.getRole() + "</td>");
            out.print("</tr>");
        out.print("</table></body><br/>");
        
        out.print("</html>");
        }else{
            out.print("<html><body><h2>No Employee Found with ID="+empId+"</h2></body></html>");
        }
    }

}

C'est une classe de servlet très simple, j'utilise @WebServlet annotation pour lui fournir le modèle d'URI.

Test de l'exemple d'application Hibernate DataSource Tomcat JNDI

Notre application est maintenant prête, exportez-la simplement en tant que fichier war et déployez-la dans le conteneur Tomcat. Vous trouverez ci-dessous quelques-unes des captures d'écran lorsque nous invoquons notre servlet d'application. Notez que je transmets le paramètre de requête empId dans la chaîne de requête de l'URL de la requête. Vous verrez également les journaux générés par notre application dans les journaux du serveur.

May 08, 2014 8:14:16 PM org.hibernate.cfg.Configuration configure
INFO: HHH000043: Configuring from resource: hibernate.cfg.xml
May 08, 2014 8:14:16 PM org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Configuration resource: hibernate.cfg.xml
May 08, 2014 8:14:16 PM org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: Configured SessionFactory: null
May 08, 2014 8:14:16 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextInitialized
INFO: Hibernate Configuration created successfully
May 08, 2014 8:14:16 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextInitialized
INFO: ServiceRegistry created successfully
May 08, 2014 8:14:16 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
May 08, 2014 8:14:17 PM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
May 08, 2014 8:14:17 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
May 08, 2014 8:14:17 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
May 08, 2014 8:14:17 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextInitialized
INFO: SessionFactory created successfully
May 08, 2014 8:14:17 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextInitialized
INFO: Hibernate SessionFactory Configured successfully
May 08, 2014 8:14:32 PM com.journaldev.servlet.hibernate.GetEmployeeByID doGet
INFO: Request Param empId=3
May 08, 2014 8:15:22 PM com.journaldev.servlet.hibernate.GetEmployeeByID doGet
INFO: Request Param empId=3

Si vous annulez le déploiement de l'application ou arrêtez le serveur, vous verrez les journaux du serveur pour détruire la SessionFactory.

May 08, 2014 11:31:16 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextDestroyed
INFO: Closing sessionFactory
May 08, 2014 11:31:16 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextDestroyed
INFO: Released Hibernate sessionFactory resource

C'est tout pour Exemple Hibernate DataSource pour le conteneur Tomcat, j'espère que c'est facile à comprendre et à mettre en œuvre. Téléchargez l'exemple de projet à partir du lien ci-dessous et jouez avec pour en savoir plus.

Télécharger le projet Hibernate DataSource