My開発メモ

JNDIとDataSourceを使ったWebアプリをつくる

TomcatのJNDIにデータベースオブジェクトを登録して、それをWebアプリから使用する。
初心者には “DriverManager” が紹介されるのであるが、実際の運用では JNDIとDataSourceを使って、データベース接続をプールして使われるので、それをやってみた。

TOMCATにDataSourceオブジェクトを登録する

WebContent/META-INF/context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
  <Resource name="jdbc/example_db" auth="Container"
            type="javax.sql.DataSource"
            maxTotal="100" maxIdle="30" maxWaitMillis="10000"
            username="sa" password=""
            driverClassName="org.h2.Driver"
            url="jdbc:h2:tcp://localhost/~/example"
            removeAbandoned="true"
            removeAbandonedTimeout="300" />
</Context>

最後の “removeAbandoned”オプションは、放棄された接続の削除機能である。

「アプリケーションが接続を長時間プールに戻さない場合、その接続は放棄されたと呼ばれます。プールは、そのような接続を自動的に閉じて、プールから削除できます。これは、接続がリークしているアプリケーションの回避策です。」

JNDI Resources HOW-TO / Apache Tomcat 8
WebContent/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"                  
         version="4.0">
  
  <description>h2sample</description>
  <resource-ref>
	<description>DB Connection</description>
	<res-ref-name>jdbc/example_db</res-ref-name>
	<res-type>javax.sql.DataSource</res-type>
	<res-auth>Container</res-auth>
  </resource-ref>         
</web-app>

あと、オプションとして、”res-sharing-scope”タグがある。JNDIリソースとの接続が共有可能か指定する。”Shareable” もしくは “Unshareable”。

アプリケーションからデータベースに接続する

データベースからデータを取得するのは、以下のクラスである。

dao.EmployeeDAO.java
package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import model.Employee;

public class EmployeeDAO {
  public List<Employee> findAll() {
    List<Employee> empList = new ArrayList<>();
    DataSource ds = null;
    try {
      Context initContext = new InitialContext();
      Context envContext = (Context) initContext.lookup("java:/comp/env");
      ds = (DataSource) envContext.lookup("jdbc/example_db");
    } catch (NamingException e) {
      e.printStackTrace();
      return null;
    }
  
    try (Connection conn = ds.getConnection();) {
      String sql = "select * from employee";
      PreparedStatement pStmt = conn.prepareStatement(sql);
      ResultSet rs = pStmt.executeQuery();
      while (rs.next()) {
        String id = rs.getString("id");
        String name = rs.getString("name");
        int age = rs.getInt("age");
        Employee emp = new Employee(id, name, age);
        empList.add(emp);
      }
    } catch (SQLException e) {
      e.printStackTrace();
      return null;
    }
    return empList;
  }
}

参考

カテゴリー: Java, memo, tomcat

タグ: DataSource, JNDI

カウント: 177