Hibernate Tomcat JNDI DataSource Beispiel-Tutorial
Wir haben bereits gesehen, wie man das Hibernate ORM-Tool in einer eigenständigen Java-Anwendung verwendet. Heute lernen wir, wie man Hibernate mit einer DataSource im Tomcat-Servlet-Container nutzt. Die Verwendung von Hibernate in einer Webanwendung ist sehr einfach. Alles, was wir tun müssen, ist, die DataSource-Eigenschaften in der Hibernate-Konfigurationsdatei zu konfigurieren. Zuerst müssen wir die Testdatenbank und die JNDI DataSource im Tomcat-Container einrichten.
Hibernate DataSource JNDI Beispiel Datenbankeinrichtung
Ich verwende MySQL für mein Beispiel. Das folgende Skript wird ausgeführt, um eine einfache Tabelle zu erstellen und einige Werte einzufügen.
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', 'Entwickler', now());
Der Name des Datenbankschemas ist TestDB.
Tomcat JNDI DataSource Konfiguration
Um den Tomcat-Container für die Initialisierung der DataSource zu konfigurieren, müssen wir einige Änderungen an den Dateien server.xml
und context.xml
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 obige Ressource in das server.xml
-Element GlobalNamingResources ein.
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. Dies ist erforderlich, damit Anwendungen auf die JNDI-Ressource mit dem Namen jdbc/MyLocalDB
zugreifen können. Starten Sie den Server einfach neu. Sie sollten keine Fehler in den Tomcat-Serverprotokollen sehen. Wenn falsche Konfigurationen vorliegen, z. B. ein falsches Passwort, erhalten Sie die entsprechende Ausnahme im Serverprotokoll. Sie müssen außerdem sicherstellen, dass die MySQL-Treiber-JAR-Datei im Tomcat-Lib-Verzeichnis vorhanden ist. Andernfalls kann Tomcat keine Datenbankverbindung erstellen, und Sie erhalten eine ClassNotFoundException
in den Protokollen. Jetzt ist unsere Datenbank- und Tomcat-Server-JNDI-Einrichtung bereit. Gehen wir zur Erstellung unserer Webanwendung mit Hibernate über.
Hibernate DataSource Beispiel Dynamisches Webprojekt
Erstellen Sie ein dynamisches Webprojekt in Eclipse und konfigurieren Sie es dann als Maven-Projekt. Unsere endgültige Projektstruktur wird wie im unten stehenden Bild aussehen.
Beachten Sie, dass ich Tomcat-7 für die Bereitstellung meines Projekts verwende und ihn dem Build-Pfad hinzugefügt habe, sodass wir die Servlet-API-Abhängigkeiten nicht separat zu unserem Projekt hinzufügen müssen. Tomcat-7 unterstützt die Servlet-3-Spezifikationen, und wir werden Annotations verwenden, um unsere Servlets zu erstellen. Falls Sie mit den Servlet-3-Annotations nicht vertraut sind, sollten Sie das „Servlet-Tutorial für Anfänger“ ansehen. Schauen wir uns nun die einzelnen Komponenten nacheinander an.
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>
Ich verwende die neueste Hibernate-Version 4.3.5.Final, und die Abhängigkeit `hibernate-core` wurde für Hibernate hinzugefügt. Die Abhängigkeit `mysql-connector-java` wurde hinzugefügt, da wir eine MySQL-Datenbank verwenden, obwohl der Scope als „provided“ angegeben ist, da sie bereits Teil der Tomcat-Container-Bibliotheken ist. Selbst wenn wir die MySQL-Treiber-Abhängigkeiten nicht hinzufügen, wird unser Projekt problemlos kompiliert und ausgeführt. Es ist jedoch besser, sie aufzunehmen, damit bei einer Überprüfung der Projektabhängigkeiten klar ersichtlich ist, dass wir eine MySQL-Datenbank verwenden.
Hibernate DataSource Konfiguration
Unsere Hibernate-Konfigurationsdatei mit DataSource 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 mit Model-Klasse, die Annotations enthält -->
<mapping class="com.journaldev.servlet.hibernate.model.Employee"/>
</session-factory>
</hibernate-configuration>
Die Eigenschaft hibernate.connection.datasource
wird verwendet, um den DataSource-Namen bereitzustellen, der von Hibernate für Datenbankoperationen verwendet wird.
Hibernate DataSource Beispiel Modellklasse
Wie Sie in der Hibernate-Konfigurationsdatei sehen können, verwenden wir Annotations in unserer Modellklasse Employee
. Unsere Model-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;
}
}
Hibernate DataSource Tomcat JNDI Servlet Listener
Da wir die Hibernate SessionFactory
initialisieren müssen, um sie in der Anwendung verwenden zu können, und außerdem die SessionFactory
beim Beenden der Webanwendung zerstört werden muss, ist die beste Methode hierfür eine Implementierung eines ServletContextListener
.
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");
}
}
Hibernate Tomcat JNDI Beispiel Servlet-Implementierung
Schreiben wir ein einfaches Servlet, bei dem wir die Mitarbeiter-ID als Anfrageparameter übergeben. Es gibt dann die Mitarbeiterinformationen aus der Datenbank zurück, wobei wir selbstverständlich Hibernate nutzen, um die Datenbank abzufragen.
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("
Mitarbeiterdetails
„);
out.print(“
");
out.print("Mitarbeiter-ID");
out.print("Name");
out.print("Rolle");
out.print("");
out.print("");
out.print("");
out.print("");
out.print("");
out.print("
“ + empId + „
“ + emp.getName() + „
“ + emp.getRole() + „
");
out.print("");
}else{
out.print("
Kein Mitarbeiter mit ID=“+empId+“ gefunden
");
}
}
}
Es handelt sich um eine sehr einfache Servlet-Klasse. Ich verwende die Annotation @WebServlet
, um das URI-Muster bereitzustellen.
Testen der Hibernate DataSource Tomcat JNDI Beispielanwendung
Unsere Anwendung ist jetzt bereit. Exportieren Sie sie einfach als WAR-Datei und stellen Sie sie im Tomcat-Container bereit. Im Folgenden sehen Sie einige Screenshots, wenn wir unser Anwendungs-Servlet aufrufen.
Beachten Sie, dass ich den Anfrageparameter empId
in der Abfragezeichenfolge der Anforderungs-URL übergebe. Sie sehen auch, dass unsere Anwendung Protokolle in den Serverprotokollen generiert.
Anwendungsprotokolle
May 08, 2014 8:14:16 PM org.hibernate.cfg.Configuration configure
INFO: HHH000043: Konfiguration aus Ressource: hibernate.cfg.xml
May 08, 2014 8:14:16 PM org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Konfigurationsressource: hibernate.cfg.xml
May 08, 2014 8:14:16 PM org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: SessionFactory konfiguriert: null
May 08, 2014 8:14:16 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextInitialized
INFO: Hibernate-Konfiguration erfolgreich erstellt
May 08, 2014 8:14:16 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextInitialized
INFO: ServiceRegistry erfolgreich erstellt
May 08, 2014 8:14:32 PM com.journaldev.servlet.hibernate.GetEmployeeByID doGet
INFO: Anfrage-Parameter empId=3
Protokolle zur Zerstörung der SessionFactory
May 08, 2014 11:31:16 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextDestroyed
INFO: Schließen der SessionFactory
May 08, 2014 11:31:16 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextDestroyed
INFO: Hibernate SessionFactory-Ressource freigegeben
Fazit
Dieses Tutorial zeigt, wie Sie Hibernate mit einer JNDI DataSource im Tomcat-Container konfigurieren. Durch die Einrichtung der Datenbank, die Konfiguration von Tomcat und die Integration von Hibernate haben wir eine einfache, skalierbare Webanwendung erstellt. Mit der richtigen Konfiguration und Debugging-Schritten können Sie Hibernate nahtlos mit robuster Datenbankkonnektivität in einer Servlet-Umgebung nutzen.