ようこそ、Tomcat DataSource JNDIの例のチュートリアルへ。前回のチュートリアルではJDBC DataSourceを見て、それをスタンドアロンのJavaアプリケーションで使用する方法を学びました。
Tomcat DataSource JNDI
DataSourceの実際の利点は、JNDI Contextと組み合わせたときに現れます。例えば、サーブレットコンテナに展開されたWebアプリケーション内のコネクションプール。多くの人気のあるサーブレットコンテナは、Resourceの構成とJNDIコンテキストを介したDataSourceへの組み込みサポートを提供しています。これにより、わずかな構成行でDataSourceコネクションプールを作成および使用できます。このチュートリアルは、Tomcat DataSource JNDIの構成例を提供することを目的としています。Apache TomcatはJNDIコンテキストでDataSourceを構成するための3つの方法を提供しています。
- アプリケーションのcontext.xml – DataSourceを設定する最も簡単な方法で、必要なのはMETA-INFディレクトリにcontext.xmlファイルがあるだけです。コンテキストファイルにResource要素を定義し、コンテナがそれを読み込んで構成するようにします。このアプローチはシンプルですが、いくつかの欠点があります。
- コンテキストファイルはWARファイルにバンドルされているため、小さな構成変更ごとに新しいWARをビルドしてデプロイする必要があります。アプリケーションが分散環境で動作する場合や、QA、IT、PRODなどの異なるテスト環境にデプロイする必要がある場合も同じ問題が発生します。
- DataSourceはコンテナによってアプリケーションの使用のために作成されるため、グローバルに使用することはできません。DataSourceを複数のアプリケーションで共有することはできません。
- 同じ名前で定義されたグローバルなDataSource(server.xml)がある場合、アプリケーションのDataSourceは無視されます。
- サーバーのcontext.xml – サーバーに複数のアプリケーションがある場合、データソースをそれらで共有したい場合は、サーバーのcontext.xmlファイルで定義できます。このファイルは
apache-tomcat/conf
ディレクトリにあります。サーバーのcontext.xmlファイルのスコープはアプリケーションですので、もし100の接続を持つDataSourceコネクションプールを定義した場合、20のアプリケーションがあれば、データソースは各アプリケーションごとに作成されます。これにより、明らかにデータベースサーバーのリソースを消費し、アプリケーションのパフォーマンスに悪影響を与えるでしょう。 - server.xmlとcontext.xml – グローバルレベルでDataSourceを定義するには、server.xmlの
GlobalNamingResources
要素でそれらを定義できます。このアプローチを使用する場合、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 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("
");
//いくつかのDB情報を出力しましょう
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データベースに接続され、以下の結果が生成されます。これでTomcat DataSource JNDI構成の例チュートリアルは以上です。同様の方法でリソースをcontext.xmlファイルに定義することもできます。
Source:
https://www.digitalocean.com/community/tutorials/tomcat-datasource-jndi-example-java