欢迎来到Tomcat DataSource JNDI示例教程。在上一个教程中,我们介绍了JDBC DataSource,并学习了如何在独立的Java应用程序中使用它。
Tomcat DataSource JNDI
数据源的实际好处是当我们将其与JNDI上下文一起使用时。例如,在部署在Servlet容器中的Web应用程序中的连接池。大多数流行的Servlet容器通过资源配置和JNDI上下文提供了对DataSource的内置支持。这帮助我们只需几行配置就可以创建和使用DataSource连接池。本教程旨在提供Tomcat DataSource JNDI配置示例。Apache Tomcat提供了三种在JNDI上下文中配置DataSource的方式。
- 应用上下文.xml – 这是配置数据源的最简单方式,我们只需要在META-INF目录下创建一个context.xml文件。我们必须在上下文文件中定义Resource元素,容器会负责加载和配置它。这种方法很简单,但它也有一些缺点;
- 由于上下文文件与WAR文件捆绑在一起,所以每次进行小的配置更改都需要构建和部署新的WAR文件。如果您的应用程序在分布式环境中运行,或者您的应用程序需要在不同的测试环境(如QA、IT、PROD等)中部署,则会遇到相同的问题。
- 数据源由容器为应用程序使用而创建,因此无法全局使用。我们无法在多个应用程序之间共享数据源。
- 如果存在具有相同名称的全局数据源(server.xml)定义,则会忽略应用程序数据源。
- 服务器 context.xml – 如果服务器中有多个应用程序,并且您想在它们之间共享 DataSource,我们可以在服务器的 context.xml 文件中定义它。该文件位于
apache-tomcat/conf
目录中。服务器 context.xml 文件的范围是应用程序,因此如果您定义了一个包含 100 个连接的 DataSource 连接池,并且有 20 个应用程序,那么将为每个应用程序创建数据源。这将导致 2000 个连接,显然会消耗所有数据库服务器资源,并影响应用程序性能。 - server.xml 和 context.xml – 我们可以通过在 server.xml 的
GlobalNamingResources
元素中定义它们,在全局级别定义 DataSource。如果采用这种方法,然后我们需要在服务器或应用程序特定的 context.xml 文件中定义一个ResourceLink
。这是在希望在服务器上运行的多个应用程序之间共享通用资源池时的首选方式。关于资源链接,是在服务器级别的 context xml 文件中定义还是在应用程序级别定义,取决于您的需求。
让我们转到 Java Web 应用程序中的 Tomcat DataSource JNDI 示例。有关测试数据设置,请参阅我关于JDBC DataSource 示例的最后一篇文章。
Tomcat数据源JNDI配置示例 – server.xml
在tomcat server.xml文件中添加以下代码。代码应添加在GlobalNamingResources
元素中。还要确保数据库驱动程序存在于tomcat lib目录中,因此在这种情况下,mysql jdbc jar必须存在于tomcat lib中。
<Resource name="jdbc/MyDB"
global="jdbc/MyDB"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/UserDB"
username="pankaj"
password="pankaj123"
maxActive="100"
maxIdle="20"
minIdle="5"
maxWait="10000"/>
这里我们正在创建名称为jdbc/MyDB
的JNDI上下文,这是一种DataSource类型。我们在url、username、password和driverClassName属性中传递数据库配置。连接池属性在maxActive、maxIdle和minIdle属性中定义。
Tomcat数据源JNDI资源链接配置 – context.xml
在服务器context.xml文件中添加以下代码。
<ResourceLink name="jdbc/MyLocalDB"
global="jdbc/MyDB"
auth="Container"
type="javax.sql.DataSource" />
注意资源链接名称与全局链接不同,我们必须在我们的Java程序中使用此名称来获取DataSource。
Tomcat DataSource JNDI 示例
创建一个名为JDBCDataSourceTomcat的动态Web应用,然后创建一个带有以下代码的Servlet。
package com.journaldev.jdbc.datasource;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
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 javax.sql.DataSource;
@WebServlet("/JDBCDataSourceExample")
public class JDBCDataSourceExample extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Context ctx = null;
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try{
ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/MyLocalDB");
con = ds.getConnection();
stmt = con.createStatement();
rs = stmt.executeQuery("select empid, name from Employee");
PrintWriter out = response.getWriter();
response.setContentType("text/html");
out.print("Employee Details
");
out.print("");
out.print("Employee ID ");
out.print("Employee Name ");
while(rs.next())
{
out.print("");
out.print("" + rs.getInt("empid") + " ");
out.print("" + rs.getString("name") + " ");
out.print(" ");
}
out.print("
");
//让我们打印一些数据库信息
out.print("Database Details
");
out.print("Database Product: "+con.getMetaData().getDatabaseProductName()+"
");
out.print("Database Driver: "+con.getMetaData().getDriverName());
out.print("");
}catch(NamingException e){
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
rs.close();
stmt.close();
con.close();
ctx.close();
} catch (SQLException e) {
System.out.println("Exception in closing DB resources");
} catch (NamingException e) {
System.out.println("Exception in closing Context");
}
}
}
}
请注意,我正在使用Servlet 3基于注解的配置,它将在Tomcat 7或更高版本中运行。如果您使用的是较低版本的Tomcat,则需要对Servlet代码进行一些修改,以删除WebServlet注解并在web.xml文件中进行配置。我们感兴趣的是Servlet代码的一部分;
ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/MyLocalDB");
获取应用程序使用的JNDI资源的方法。我们也可以以这种方式编写它;
ctx = new InitialContext();
Context initCtx = (Context) ctx.lookup("java:/comp/env");
DataSource ds = (DataSource) initCtx.lookup("jdbc/MyLocalDB");
I am also printing some database information to check which database we are connected. Now when you will run the application, you will see following output. Let’s see how easy it is to switch the database server because we are using Tomcat DataSource. All you need is to change the Database properties. So if we have to switch to Oracle database, my Resource configuration will look like below.
<Resource name="jdbc/MyDB"
global="jdbc/MyDB"
auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@localhost:1521:orcl"
username="hr"
password="oracle"
maxActive="100"
maxIdle="20"
minIdle="5"
maxWait="10000"/>
当我们重新启动服务器并运行应用程序时,它将连接到Oracle数据库并生成以下结果。这就是Tomcat DataSource JNDI配置示例教程的全部内容,您还可以在context.xml文件中以类似的方式定义资源。
Source:
https://www.digitalocean.com/community/tutorials/tomcat-datasource-jndi-example-java