歡迎來到Tomcat DataSource JNDI示例教程。我們在上一個教程中看過JDBC DataSource,並學習了如何在獨立的Java應用程序中使用它。
Tomcat DataSource JNDI
DataSource的實際好處在於與JNDI Context一起使用時。例如,在Servlet容器中部署的Web應用程序中的連接池。大多數流行的Servlet容器通過資源配置和JNDI上下文提供內置支持來DataSource。這幫助我們僅通過幾行配置即可創建和使用DataSource連接池。本教程旨在提供Tomcat DataSource JNDI配置示例。Apache Tomcat提供了在JNDI上下文中配置DataSource的三種方法。
- 應用程式 context.xml – 這是配置 DataSource 的最簡單方法,我們只需要在 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 個應用程式,那麼每個應用程式將會建立 DataSource。這將導致 2000 個連線,顯然會消耗所有資料庫伺服器資源,影響應用程式的效能。 - server.xml 和 context.xml – 我們可以在 server.xml 的
GlobalNamingResources
元素中定義全域級別的 DataSource。如果採用此方法,則需要從伺服器或應用程式特定的 context.xml 檔案中定義一個ResourceLink
。當您希望在伺服器上運行的多個應用程式之間共用共同資源池時,這是首選的方法。關於資源連結,是在伺服器級別的 context xml 檔案還是應用程式級別取決於您的需求。
讓我們來看看在 Java Web 應用程式中的 Tomcat DataSource JNDI 範例。有關測試數據設置,請參閱我的上一篇文章,關於 JDBC DataSource 範例。
Tomcat DataSource 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 DataSource JNDI資源鏈接配置 – context.xml
在服務器context.xml文件中添加以下代碼。
<ResourceLink name="jdbc/MyLocalDB"
global="jdbc/MyDB"
auth="Container"
type="javax.sql.DataSource" />
請注意,資源鏈接名稱與全局鏈接不同,我們必須在我們的Java程序中使用此名稱來獲取DataSource。
Tomcat 數據源 JNDI 示例
創建一個名為
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 數據源 JNDI 配置示例教程的全部內容,您也可以在 context.xml 文件中以類似的方式定義資源。
Source:
https://www.digitalocean.com/community/tutorials/tomcat-datasource-jndi-example-java