JavaでのTomcatデータソースJNDIの例

TomcatのDataSource JNDIの例チュートリアルへようこそ。前のチュートリアルではJDBC DataSourceを見て、それをスタンドアロンのJavaアプリケーションで使う方法を学びました。

トムキャットのデータソースJNDI

DataSourceをJNDIコンテキストと一緒に使用することで、実際の利点が得られます。たとえば、サーブレットコンテナに展開されたWebアプリケーションの接続プールの場合です。多くの人気のあるサーブレットコンテナは、リソースの設定とJNDIコンテキストを介してDataSourceの組み込みサポートを提供しています。これによって、わずかな構成行数でDataSource接続プールを作成して使用することができます。このチュートリアルは、Tomcat DataSourceのJNDI設定例を提供することを目的としています。Apache Tomcatでは、JNDIコンテキストでDataSourceを設定するための3つの方法が提供されています。

    1. アプリケーションのcontext.xml – これはDataSourceを設定する最も簡単な方法であり、必要なのはMETA-INFディレクトリにあるcontext.xmlファイルだけです。contextファイルにResource要素を定義し、コンテナが読み込みと設定を担当します。この方法は簡単ですが、いくつかの欠点があります。

contextファイルはWARファイルにバンドルされているため、小さな設定変更のたびに新しいWARをビルドして展開する必要があります。アプリケーションが分散環境で動作する場合や、テスト環境(例:QA、IT、PRODなど)に展開する必要がある場合も同じ問題が発生します。
データソースはアプリケーションの使用のためにコンテナによって作成されるため、グローバルに使用することはできません。データソースを複数のアプリケーションで共有することはできません。
同じ名前で定義されたグローバルデータソース(server.xml)がある場合、アプリケーションのデータソースは無視されます。

サーバのcontext.xml – サーバに複数のアプリケーションがあり、それらの間でDataSourceを共有したい場合、サーバのcontext.xmlファイルにそれを定義することができます。このファイルはapache-tomcat/confディレクトリにあります。server context.xmlファイルの範囲はアプリケーションです。したがって、100の接続を持つデータソースの接続プールを定義し、20のアプリケーションがある場合、データソースは各アプリケーションごとに作成されます。これにより、データベースサーバのリソースをすべて消費し、アプリケーションのパフォーマンスに悪影響を及ぼします。
server.xmlとcontext.xml – グローバルレベルでDataSourceを定義するために、server.xmlのGlobalNamingResources要素にそれらを定義することができます。このアプローチを使用する場合は、serverまたはアプリケーション固有のcontext xmlファイルからResourceLinkを定義する必要があります。これは、サーバ上で実行されている複数のアプリケーション間で共有する共通のリソースプールを共有する場合に適した方法です。リソースリンクをserverレベルのcontext xmlファイルまたはアプリケーションレベルのcontext xmlファイルに定義するかは、要件によります。

Javaウェブアプリケーションでの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="scdev" 
      password="scdev123" 
      
      maxActive="100" 
      maxIdle="20" 
      minIdle="5" 
      maxWait="10000"/>

ここでは、DataSourceの一種であるjdbc/MyDBという名前でJNDIコンテキストを作成しています。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" />

リソースリンク名がグローバルリンクと異なることに注意してください。DataSourceを取得するために、Javaプログラムでこの名前を使用する必要があります。

「TomcatのDataSource JNDIの例」

JDBCDataSourceTomcatという名前のダイナミックなウェブアプリケーションを作成し、以下のコードでServletを作成してください。

package com.scdev.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("<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>");
            
            while(rs.next())
            {
                out.print("<tr>");
                out.print("<td>" + rs.getInt("empid") + "</td>");
                out.print("<td>" + rs.getString("name") + "</td>");
                out.print("</tr>");
            }
            out.print("</table></body><br/>");
            
            //lets print some DB information
            out.print("<h3>Database Details</h3>");
            out.print("Database Product: "+con.getMetaData().getDatabaseProductName()+"<br/>");
            out.print("Database Driver: "+con.getMetaData().getDriverName());
            out.print("</html>");
            
		}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");

私は、接続しているデータベースを確認するために、いくつかのデータベース情報も印刷しています。今、アプリケーションを実行すると、以下の出力が表示されます。Tomcatのデータソースを使用しているので、データベースサーバーを簡単に切り替えることができるかどうか見てみましょう。必要なのはデータベースのプロパティを変更するだけです。Oracleデータベースに切り替える場合、私のリソース設定は以下のようになります。

<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ファイルでも同じようにリソースを定義することができます。

コメントを残す 0

Your email address will not be published. Required fields are marked *