Hibernate Tomcat JNDI DataSource Beispiel Tutorial

Willkommen zum Beispiel-Tutorial für Hibernate Tomcat JNDI DataSource. Wir haben bereits gesehen, wie man das Hibernate ORM-Tool in einer eigenständigen Java-Anwendung verwendet. Heute werden wir lernen, wie man Hibernate mit DataSource im Tomcat-Servlet-Container verwendet. Die Verwendung von Hibernate in einer Webanwendung ist sehr einfach, alles was wir brauchen, ist die Konfiguration der DataSource-Eigenschaften in der Hibernate-Konfigurationsdatei. Zunächst müssen wir eine Testdatenbank und eine JNDI DataSource im Tomcat-Container einrichten.

Beispiel für die Konfiguration einer Hibernate DataSource JNDI

I am using MySQL for my example, below script is executed to create a simple table and insert some values into it. 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());

Der Name des Datenbankschemas lautet TestDB.

Konfiguration der Tomcat JNDI DataSource

Um den Tomcat-Container zur Initialisierung der DataSource zu konfigurieren, müssen wir einige Änderungen in den Dateien server.xml und context.xml von Tomcat vornehmen. 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"/>

Fügen Sie die oben genannte Ressource im Element GlobalNamingResources in der server.xml hinzu. context.xml

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

Fügen Sie den obigen ResourceLink in die context.xml-Datei ein. Es ist erforderlich, damit Anwendungen auf die JNDI-Ressource mit dem Namen jdbc/MyLocalDB zugreifen können. Starten Sie einfach den Server neu, und es sollten keine Fehler in den Tomcat-Serverprotokollen angezeigt werden. Falls es falsche Konfigurationen gibt, wie ein falsches Passwort, wird die entsprechende Ausnahme im Serverprotokoll angezeigt. Stellen Sie außerdem sicher, dass die MySQL-Treiber-JAR-Datei im Tomcat lib-Verzeichnis vorhanden ist. Andernfalls kann Tomcat keine Datenbankverbindung herstellen, und Sie erhalten in den Protokollen eine ClassNotFoundException. Nun ist unsere Datenbank- und Tomcat-Server-JNDI-Konfiguration bereit. Lassen Sie uns nun zur Erstellung unserer Webanwendung mit Hibernate übergehen.

Hibernate DataSource Beispiel Dynamic Web Project

Erstellen Sie ein dynamisches Webprojekt in Eclipse und konfigurieren Sie es dann als Maven-Projekt. Unsere endgültige Projektstruktur wird wie im folgenden Bild aussehen. Beachten Sie, dass ich Tomcat-7 für die Bereitstellung meines Projekts verwende und es zum Build-Pfad hinzugefügt habe, sodass wir Servlet-API-Abhängigkeiten nicht separat hinzufügen müssen. Tomcat-7 unterstützt Servlet 3-Spezifikationen, und wir werden Annotationen verwenden, um unsere Servlets zu erstellen. Wenn Sie mit Servlet 3-Annotationen nicht vertraut sind, sollten Sie sich das Servlet-Tutorial für Anfänger ansehen. Lassen Sie uns nun jeden der Komponenten einzeln betrachten.

Hibernate Maven-Abhängigkeiten

Unsere endgültige pom.xml-Datei sieht wie folgt aus.

<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>

I am using Hibernate latest version 4.3.5.Final, hibernate-core dependency is added for Hibernate. mysql-connector-java dependency is added because we are using MySQL database, although scope is provided because it’s already part of the tomcat container libraries. Even if we don’t add MySQL driver dependencies, our project will compile and run fine. However it’s better to include it so that if someone will look into the project dependencies, it will be clear that we are using MySQL database.

Hibernate DataSource-Konfiguration

Unsere Hibernate-Konfigurationsdatei mit dem Datenquellenbereich sieht wie folgt aus. 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>

Die hibernate.connection.datasource-Eigenschaft wird verwendet, um den Namen der DataSource anzugeben, die von Hibernate für Datenbankoperationen verwendet wird.

Beispielmodellklasse für Hibernate DataSource

Wie Sie in der Hibernate-Konfigurationsdatei sehen können, verwenden wir Annotationen in unserer Modellklasse Employee. Unser Modell-Bean sieht wie folgt aus. 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;
	}
}

Das Modell-Bean ist dasselbe wie das, das wir im Hibernate-Anfänger-Tutorial verwendet haben. Sie sollten es überprüfen, wenn Sie Verwirrung bezüglich einer der verwendeten Annotationen haben.

Hibernate DataSource Tomcat JNDI Servlet-Listener

Weil wir die Hibernate SessionFactory initialisieren müssen, um sie in der Anwendung zu verwenden, und auch wenn die Webanwendung zerstört wird, müssen wir die SessionFactory zerstören. Der beste Ort, um dies zu tun, ist in einer ServletContextListener-Implementierung. 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");
    }
	
}

Wenn Sie nicht mit Servlet-Listenern vertraut sind, lesen Sie bitte das Servlet Listener Tutorial.

Beispiel für Hibernate Tomcat JNDI Implementierung eines Servlets

Lassen Sie uns ein einfaches Servlet schreiben, in dem wir die Mitarbeiter-ID als Anforderungsparameter übergeben und die Mitarbeiterinformationen aus der Datenbank ausgeben. Offensichtlich werden wir Hibernate verwenden, um die Datenbank abzufragen und Mitarbeiterinformationen zu erhalten. 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>");
        }
	}

}

Es ist eine sehr einfache Servlet-Klasse, ich verwende die @WebServlet-Annotation, um das URI-Muster dafür bereitzustellen.

Testen der Hibernate DataSource Tomcat JNDI Beispielanwendung

Unsere Anwendung ist jetzt bereit, exportieren Sie sie einfach als WAR-Datei und deployen Sie sie im Tomcat-Container. Unten sind einige Screenshots, wenn wir unseren Anwendungsservlet aufrufen. Beachten Sie, dass ich den empId-Anforderungsparameter in der Anforderungs-URL-Abfragezeichenfolge übergebe. Sie werden auch unsere Anwendungsprotokolle in den Serverprotokollen sehen.

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

Wenn Sie die Anwendung deinstallieren oder den Server stoppen, werden Sie Serverprotokolle zum Zerstören der SessionFactory sehen.

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

Das ist alles für das Hibernate DataSource Beispiel für den Tomcat-Container, ich hoffe, es ist einfach zu verstehen und umzusetzen. Laden Sie das Beispielprojekt über den unten stehenden Link herunter und spielen Sie damit herum, um mehr zu lernen.

Download Hibernate DataSource Projekt

Source:
https://www.digitalocean.com/community/tutorials/hibernate-tomcat-jndi-datasource-example-tutorial