Hibernate Tomcat JNDI数据源示例教程

Welcome to the Hibernate Tomcat JNDI DataSource example tutorial. We have already seen how to use Hibernate ORM tool in standalone java application, today we will learn how to use Hibernate with DataSource in Tomcat servlet container.

欢迎使用Hibernate Tomcat JNDI DataSource示例教程。 我们已经了解了如何在独立的Java应用程序中使用Hibernate ORM工具 ,今天我们将学习如何在Tomcat Servlet容器中将Hibernate与DataSource一起使用。

Using hibernate in web application is very easy, all we need is to configure DataSource properties in hibernate configuration file. First of all we need to setup test database and JNDI DataSource in tomcat container.

在Web应用程序中使用Hibernate非常容易,我们所需DataSource就是在Hibernate配置文件中配置DataSource属性。 首先,我们需要在tomcat容器中设置测试数据库和JNDI DataSource。

Hibernate DataSource JNDI示例数据库设置 (Hibernate DataSource JNDI Example Database Setup)

I am using MySQL for my example, below script is executed to create a simple table and insert some values into it.

我使用MySQL作为示例,执行以下脚本以创建一个简单表并将一些值插入其中。

employee.sql

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());

The Database schema name is TestDB.

数据库模式名称为TestDB

Tomcat JNDI数据源配置 (Tomcat JNDI DataSource Configuration)

For configuring tomcat container to initialize DataSource, we need to make some changes in tomcat server.xml and context.xml files.

为了配置tomcat容器以初始化DataSource,我们需要对tomcat server.xml和context.xml文件进行一些更改。

server.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"/>

Add above resource in the server.xml GlobalNamingResources element.

在server.xml GlobalNamingResources元素中添加以上资源。

context.xml

context.xml

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

Add above ResourceLink in the context.xml file, it’s required so that applications can access the JNDI resource with name jdbc/MyLocalDB.

在context.xml文件中添加以上ResourceLink ,这是必需的,以便应用程序可以使用名称jdbc/MyLocalDB访问JNDI资源。

Just restart the server, you should not see any errors in the tomcat server logs. If there are any wrong configurations, such as password is wrong, you will get the corresponding exception in the server log.

只需重新启动服务器,您就不会在tomcat服务器日志中看到任何错误。 如果有任何错误的配置,例如密码错误,您将在服务器日志中得到相应的异常。

You also need to make sure that MySQL driver jar file is inside the tomcat lib directory, otherwise tomcat will not be able to create database connection and you will get ClassNotFoundException in logs.

您还需要确保MySQL驱动程序jar文件位于tomcat lib目录中,否则tomcat将无法创建数据库连接,并且您将在日志中获取ClassNotFoundException

Now our database and tomcat server JNDI setup is ready, let’s move to create our web application using hibernate.

现在我们的数据库和tomcat服务器JNDI设置已经准备就绪,让我们开始使用hibernate创建我们的Web应用程序。

Hibernate DataSource示例动态Web项目 (Hibernate DataSource Example Dynamic Web Project)

Create a dynamic web project in Eclipse and then configure it as Maven project. Our final project structure will look like below image.

在Eclipse中创建一个动态Web项目,然后将其配置为Maven项目。 我们的最终项目结构将如下图所示。

Note that I am using Tomcat-7 for my project deployment and I have added it to the build path, so that we don’t need to separately add Servlet API dependencies in our project.

请注意,我正在使用Tomcat-7进行项目部署,并且已将其添加到构建路径中,因此我们无需在项目中单独添加Servlet API依赖项。

Tomcat-7 supports Servlet 3 specs and we will be using annotations to create our servlets. If you are not familiar with Servlet 3 annotations, you should check out Servlet Tutorial for Beginners.

Tomcat-7支持Servlet 3规范 ,我们将使用批注来创建Servlet。 如果您不熟悉Servlet 3批注,则应该查看Servlet Tutorial for Beginners

Let’s look into each of the components one by one.

让我们逐一研究每个组件。

HibernateMaven依赖关系 (Hibernate Maven Dependencies)

Our final pom.xml file looks like below.

我们最终的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.

我正在使用Hibernate最新版本4.3.5.Final ,为Hibernate添加了hibernate-core依赖项。 mysql-connector-java依赖项是因为我们正在使用MySQL数据库,尽管提供了范围是因为它已经是tomcat容器库的一部分。

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.

即使我们不添加MySQL驱动程序依赖项,我们的项目也可以编译并正常运行。 但是最好包含它,这样,如果有人研究项目依赖项,很明显我们正在使用MySQL数据库。

Hibernate数据源配置 (Hibernate DataSource Configuration)

Our hibernate configuration file with datasource looks like below.

我们的带有数据源的Hibernate配置文件如下所示。

hibernate.cfg.xml

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 property is used to provide the DataSource name that will be used by Hibernate for database operations.

hibernate.connection.datasource属性用于提供将由Hibernate用于数据库操作的数据源名称。

Hibernate DataSource示例模型类 (Hibernate DataSource Example Model Class)

As you can see in hibernate configuration file, we are using annotations in our model class Employee. Our model bean looks like below.

正如您在Hibernate配置文件中看到的那样,我们在模型类Employee中使用注释。 我们的模型bean如下所示。

Employee.java

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

Model bean is same as we used in Hibernate Beginners Tutorial, you should check it out if you have any confusion related to any of the annotations used.

Model bean与Hibernate Beginners Tutorial中使用的一样,您应该检查一下是否与使用的任何注释有关。

Hibernate数据源Tomcat JNDI Servlet侦听器 (Hibernate DataSource Tomcat JNDI Servlet Listener)

Since we have to initialize Hibernate SessionFactory because we can use it in the application and also when web application is destroyed, we need to destroy SessionFactory. So the best place to do this in a ServletContextListener implementation.

由于我们必须初始化Hibernate SessionFactory因为我们可以在应用程序中以及在Web应用程序被销毁时使用它,因此我们需要销毁SessionFactory。 因此,在ServletContextListener实现中执行此操作的最佳位置。

HibernateSessionFactoryListener.java

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");
    }
	
}

If you are not familiar with servlet listeners, please read Servlet Listener Tutorial.

如果您不熟悉servlet侦听器,请阅读Servlet Listener Tutorial

Hibernate Tomcat JNDI示例Servlet实现 (Hibernate Tomcat JNDI Example Servlet Implementation)

Let’s write a simple servlet where we will pass employee id as request parameter and it will print out the employee information from database, obviously we will use Hibernate to query the database and get employee information.

让我们编写一个简单的servlet,在其中我们将雇员ID作为请求参数传递,它将从数据库中打印出雇员信息,显然,我们将使用Hibernate来查询数据库并获取雇员信息。

GetEmployeeByID.java

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>");
        }
	}

}

It’s a very simple servlet class, I am using @WebServlet annotation to provide the URI pattern for it.

这是一个非常简单的servlet类,我使用@WebServlet批注为其提供URI模式。

测试Hibernate DataSource Tomcat JNDI示例应用程序 (Testing Hibernate DataSource Tomcat JNDI Example Application)

Our application is ready now, just export as war file and deploy it in the tomcat container. Below are some of the screenshots when we invoke our application servlet.

我们的应用程序现已准备就绪,只需将其导出为war文件并将其部署在tomcat容器中即可。 下面是调用应用程序servlet时的一些屏幕截图。

Notice that I am passing empId request parameter in the request URL query string. You will also see our application generated logs in the server logs.

请注意,我在请求URL查询字符串中传递了empId请求参数。 您还将在服务器日志中看到我们的应用程序生成的日志。

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

If you will undeploy the application or stop the server, you will see server logs for destroying the SessionFactory.

如果您取消部署应用程序或停止服务器,则会看到用于销毁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

That’s all for Hibernate DataSource example for tomcat container, I hope it’s easy to understand and implement. Download the sample project from below link and play around with it to learn more.

以上就是有关tomcat容器的Hibernate DataSource示例 ,我希望它易于理解和实现。 从下面的链接下载示例项目,并进行试用以了解更多信息。

翻译自: https://www.journaldev.com/2905/hibernate-tomcat-jndi-datasource-example-tutorial

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值