歡迎來到 Hibernate Tomcat JNDI DataSource 範例教程。我們已經看過如何在獨立的 Java 應用程式中使用 Hibernate ORM 工具,今天我們將學習如何在 Tomcat servlet 容器中使用 Hibernate 與 DataSource。在網頁應用程式中使用 Hibernate 非常簡單,我們只需要在 Hibernate 設定檔中配置 DataSource 屬性即可。首先,我們需要在 Tomcat 容器中設置測試資料庫和 JNDI DataSource。
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());
資料庫架構名稱為 TestDB。
Tomcat JNDI DataSource 配置
為了配置 Tomcat 容器以初始化 DataSource,我們需要在 Tomcat 的 server.xml 和 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"/>
在 GlobalNamingResources
元素中添加上述資源。context.xml
<ResourceLink name="jdbc/MyLocalDB"
global="jdbc/MyLocalDB"
auth="Container"
type="javax.sql.DataSource" />
在`context.xml`文件中添加上述`ResourceLink
`,这是必需的,以便应用程序可以访问名称为`jdbc/MyLocalDB
`的JNDI资源。只需重新启动服务器,您在Tomcat服务器日志中不应该看到任何错误。如果存在任何错误配置,例如密码错误,您将在服务器日志中收到相应的异常。还需要确保MySQL驱动程序JAR文件位于Tomcat的lib目录中,否则Tomcat将无法创建数据库连接,您将在日志中收到`ClassNotFoundException
`。现在我们的数据库和Tomcat服务器JNDI设置已准备就绪,让我们开始使用Hibernate创建我们的Web应用程序。
Hibernate数据源示例动态Web项目
在Eclipse中創建一個動態 Web 項目,然後將其配置為 Maven 項目。我們最終的項目結構將如下圖所示。請注意,我正在使用Tomcat-7進行項目部署,並將其添加到構建路徑中,這樣我們就不需要在項目中單獨添加 Servlet API 依賴。Tomcat-7 支持Servlet 3 specs,我們將使用註釋來創建我們的 Servlet。如果你對 Servlet 3 註釋不熟悉,你應該查看初學者的 Servlet 教程。讓我們逐個查看每個組件。
Hibernate Maven 依賴
我們最終的 pom.xml 文件如下所示。
<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 數據源配置
我們的 Hibernate 配置文件與數據源如下所示。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` 屬性用於提供數據操作中 Hibernate 將使用的數據源名稱。
Hibernate 數據源示例模型類
正如您在 Hibernate 配置文件中所看到的,我們在我們的模型類 Employee 中使用了註釋。我們的模型 Bean 如下所示。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;
}
}
模型 Bean 與我們在 Hibernate 初學者教程 中使用的相同,如果您對使用的任何註釋感到困惑,您應該查看它。
Hibernate 數據源 Tomcat JNDI Servlet 監聽器
由於我們必須初始化 Hibernate `SessionFactory`,因為我們可以在應用程序中使用它,並且在 Web 應用程序被銷毀時也需要銷毀 SessionFactory。因此,在 `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");
}
}
如果您对Servlet监听器不熟悉,请阅读Servlet Listener Tutorial。
Hibernate Tomcat JNDI Example Servlet Implementation
让我们编写一个简单的servlet,在其中将员工ID作为请求参数传递,然后从数据库打印出员工信息,显然我们将使用Hibernate查询数据库并获取员工信息。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>");
}
}
}
这是一个非常简单的servlet类,我使用@WebServlet
注解为其提供URI模式。
测试Hibernate DataSource Tomcat JNDI Example Application
我們的應用程式現在已經準備就緒,只需將其導出為war檔案並部署到tomcat容器中。以下是我們調用應用程式servlet時的一些螢幕截圖。
請注意,我正在將empId請求參數傳遞到請求URL查詢字符串中。您還將在伺服器日誌中看到我們應用程式生成的日誌。
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
如果您將應用程式卸載或停止伺服器,您將在伺服器日誌中看到銷毀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
這就是關於tomcat容器中的Hibernate數據源示例的全部內容,我希望這樣易於理解和實施。從以下鏈接下載示例項目並進行更多操作以進行學習。
Source:
https://www.digitalocean.com/community/tutorials/hibernate-tomcat-jndi-datasource-example-tutorial