Добро пожаловать в учебник примера использования Tomcat DataSource JNDI. Мы рассмотрели JDBC DataSource в последнем уроке и узнали, как использовать его в автономном приложении на Java.
Tomcat DataSource JNDI
Реальная выгода от использования DataSource проявляется, когда мы используем его с JNDI Context. Например, пул подключений в веб-приложении, развернутом в контейнере сервлетов. Большинство популярных контейнеров сервлетов предоставляют встроенную поддержку DataSource через конфигурацию ресурсов и контекста JNDI. Это помогает нам создавать и использовать пул подключений DataSource с всего лишь несколькими строками конфигурации. В этом уроке представлен пример конфигурации Tomcat DataSource JNDI. Apache Tomcat предоставляет три способа настройки DataSource в контексте JNDI.
- Контекст application.xml – Это самый простой способ настройки DataSource, все, что нам нужно, это файл context.xml в директории META-INF. Мы должны определить элемент Resource в файле контекста, и контейнер возьмет на себя загрузку и настройку. Подход прост, но у него есть некоторые недостатки;
- Поскольку файл контекста упакован вместе с WAR-файлом, нам нужно собирать и развертывать новый WAR при каждом небольшом изменении конфигурации. Та же проблема возникает, если ваше приложение работает в распределенной среде или ваше приложение должно быть развернуто в различных тестовых средах, таких как QA, IT, PROD и т.д.
- Источник данных создается контейнером только для использования приложением, поэтому он не может использоваться глобально. Мы не можем делиться источником данных между несколькими приложениями.
- Если существует глобальный источник данных (server.xml) с тем же именем, источник данных приложения игнорируется.
- Файл контекста сервера – Если на сервере есть несколько приложений, и вы хотите использовать DataSource для общего доступа между ними, мы можем определить это в файле контекста сервера context.xml. Этот файл расположен в каталоге
apache-tomcat/conf
. Область действия файла context.xml сервера ограничена приложением, поэтому если вы определите пул подключений DataSource из 100 соединений и существует 20 приложений, то источник данных будет создан для каждого из приложений. Это приведет к созданию 2000 соединений, что, очевидно, приведет к полному использованию ресурсов сервера базы данных и ухудшению производительности приложения. - Файлы server.xml и context.xml – Мы можем определить DataSource на глобальном уровне, определив их в элементе
GlobalNamingResources
файла server.xml. Если мы используем этот подход, то нам нужно определитьResourceLink
из файла context.xml сервера или конкретного приложения. Этот способ предпочтителен, когда вы хотите использовать общий пул ресурсов между несколькими приложениями, работающими на сервере. Что касается ссылки на ресурсы, определение ее на уровне контекста файла xml сервера или на уровне приложения зависит от ваших требований.
Перейдем к примеру JNDI источника данных Tomcat в веб-приложении Java. Для настройки тестовых данных обратитесь, пожалуйста, к моей последней статье о Примере использования JDBC DataSource.
Пример конфигурации источника данных JNDI для Tomcat – файл server.xml
Добавьте нижеприведенный код в файл server.xml Tomcat. Код должен быть добавлен в элемент GlobalNamingResources
. Также убедитесь, что драйвер базы данных присутствует в каталоге lib Tomcat, поэтому в данном случае jar-файл jdbc mysql должен быть присутствует в каталоге lib Tomcat.
<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"/>
Здесь мы создаем контекст JNDI с именем jdbc/MyDB
, который является типом DataSource. Мы передаем конфигурации базы данных в атрибут url, username, password и driverClassName. Свойства пула соединений определены в атрибутах maxActive, maxIdle и minIdle.
Конфигурация связи ресурсов JNDI DataSource для Tomcat – файл context.xml
Добавьте нижеуказанный код в файл контекста сервера context.xml.
<ResourceLink name="jdbc/MyLocalDB"
global="jdbc/MyDB"
auth="Container"
type="javax.sql.DataSource" />
Обратите внимание, что имя ссылки на ресурс отличается от глобальной ссылки, мы должны использовать это имя в нашей программе Java для получения DataSource.
Пример использования DataSource JNDI в Tomcat
Создайте динамическое веб-приложение с именем JDBCDataSourceTomcat, а затем создайте сервлет со следующим кодом.
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, вам потребуется внести некоторые изменения в код сервлета, чтобы удалить аннотацию WebServlet и настроить в файле web.xml. Часть кода сервлета, которая нас интересует;
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 и выдаст следующий результат. Вот и всё, что касается примера конфигурации исходного кода DataSource JNDI в Tomcat, вы можете определить ресурс аналогичным образом в файлах context.xml тоже.
Source:
https://www.digitalocean.com/community/tutorials/tomcat-datasource-jndi-example-java