けんとのブログ

ぼやき&開発メモ

コネクションプーリング(DataSource編)

2008年12月01日 22時36分01秒 | コネクションプーリング
データベースへの接続には時間がかかります。
そのため何度も同じデータベースに接続を繰り返すような場合には、接続をプールに保管しておくほうがよいことになります。
また、直接プログラム中に、接続手順を記述するよりは、次のようにするほうがよくなります。

1.データベースへの接続の手順など (Data Source) に「名前」を付ける。
2.そして、この「名前」から Data Source を獲得する。
3.さらに、この Data Source を経由して、データベースとの接続を確立する。

「名前」を処理するために JNDI 名前空間 (JNDI namespace) が使用されます。

注意
JNDI (Java Naming and Directory Interface) とは「名前」によって、データなどを探す機能のことです。
例えば以下に大雑把な説明があります。
・Java Naming and Directory Interface (JNDI) (sun のページ)
・Java Naming and Directory Interface (英語版の wikipedia)
データベースに限定すれば、データベースに「名前」を付けておいて、「名前」だけでデータベースの処理をする機能です。
この「名前空間」はフォルダと類似の形 (あるいは XML ファイルと類似の構造) をしており、
定義された「名前」は「java:comp/env」の下におかれる。
「名前」が例えば「jdbc/mypages」であれば、
名前空間における位置は「java:comp/env/jdbc/mypages」となる。プログラムの流れは次のようになります。


// 名前付けのコンテキスト (部分) を探す (lookup)
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");

// 名前から DataSource を獲得
DataSource ds = (DataSource) envCtx.lookup("jdbc/mypages");

// DataSource から接続を獲得
Connection conn=ds.getConnection();
........
// ここで色々な作業をする。
........
// 接続を閉じる
conn.close();

次のように一度に、DataSouce を探してもよい。

Context initCtx = new InitialContext();

DataSource ds = (DataSource) envCtx.lookup("java:comp/env/jdbc/mypages");

Connection conn=ds.getConnection();

.........

conn.close();

注意
Context, InitialContext はパッケージ javax.naming に属し、 DataSource はパッケージ javax.sql に属している。
Context はインターフェースで、InitialContext はその実装クラスである


server.xmlの記述

<Context docBase="mypages" path="/mypages" reloadable="true">
<Resource name="jdbc/mypages" auth="Container" username="root" password="root"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/mydata?useUnicode=true&characterEncoding=sjis"
maxActive="8" maxIdle="8" />
</Context>

Resouce タグの属性は、

name データソースの名前 (JNDI 名)
auth プログラムでログインの手順を書くか、
コンテナー (Tomcat) がログインするかの指定 (通常は Container)
type データソースのタイプ、クラスもしくはインターフェースの正式名称
driverClassName 使用する JDBC ドライバの正式名称
maxActive コネクション・プールの最大数
maxIdle コネクション・プールでアイドルであるものの最大数
maxWait 利用可能な接続がないときに接続が返されるまで待つ最大時間 (ミリ秒)
password データベースのパスワード
url JDBCドライバーに手渡される接続 URL
username データベースのユーザ名
ValidationQuery 接続を確認するための SQL 文、SELECT 文で返す結果があるものでないといけない

注意
url に & が含まれる場合には & で置き換える必要がある。(XML と同じ制約)
無指定であれば maxActive, maxIdle は 8 で、maxWait は無限である。次を参照のこと。

Resource タグの name, type, auth 属性はそれぞれ、
web.xml の resource-ref 要素の子要素である res-ref-name, res-type, res-auth の中身に一致しないといけない。


web.xml の記述

<resource-ref>
<res-ref-name>jdbc/mypages</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>

以上

参考HP「http://mail2.nara-edu.ac.jp/~asait/java/tomcat/tomcat.htm」

これでeclipseでtomcatを再起動させると、
「javax.servlet.ServletException: Cannot load JDBC driver class 'com.mysql.jdbc.Driver'」
のエラーで怒られる。
「ビルド・パスの構成」で、JDBCドライバ「mysql-connector-java-5.1.7-bin.jar」をTomcatより先に読み込ませても同じエラー。


Tomcatにコネクションプーリング(データベースとの接続をずっと繋げっぱなしにしてくれる機能)を任せる場合は、
Tomcat5.5のドキュメントの該当部分に
http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html
引用:
--------------------------------------------------------------------------------
1. Install Your JDBC Driver

Use of the JDBC Data Sources JNDI Resource Factory requires that you make an appropriate JDBC driver available to both Tomcat internal classes and to your web application. This is most easily accomplished by installing the driver's JAR file(s) into the $CATALINA_HOME/common/lib directory, which makes the driver available both to the resource factory and to your application.

--------------------------------------------------------------------------------

とあるので、やはりTomcatインストールディレクトリの下の
/commn/lib にJDBCドライバを設置する必要があるみたいですよ。

NetBeans4.1用の解説
http://www.netbeans.org/kb/41/using-netbeans/dbconn_ja.html
引用:
--------------------------------------------------------------------------------

データベースドライバを IDE から使用できるようにしても、
Web アプリケーションからそのドライバを使用できるわけではないことに注意してください。
つまり、IDE を使用してデータベースにアクセスし、変更することはできますが、
Web アプリケーションからデータベースにアクセスして変更することは、まだできません。
これが行えるようにするには、データベースドライバの JAR ファイルを Web アプリケーションの
WEB-INF/lib フォルダ (Tomcat 接続プール機能の場合は、Tomcat の common/lib フォルダ) に追加する必要があります 。

--------------------------------------------------------------------------------

とのこと。
参考HP「http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=33165&forum=12&7」

また、server.xmlの記述はTomcatのバージョンによって違うみたいなので要注意。
下記の書き方は古いバージョンの書き方。
<ResourceParams name="jdbc/MySQL">
<parameter>
<name>username</name>
<value></value>
</parameter>
<parameter>
<name>password</name>
<value></value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>org.gjt.mm.mysql.Driver</value></parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql:///hellodb?useUnicode=true&characterEncoding=SJIS</value>
</parameter>
</ResourceParams>

今回行った書き方が新しいバージョンの書き方。正確にどのバージョンからは調べてないです・・
ちなみに、5.5系のリファレンス引用すると、
「http://jakarta.apache.org/tomcat/tomcat-5.5-doc/jndi-datasource-examples-howto.html」

<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource" username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/javatest?autoReconnect=true"/>

となってます。


また、server.xmlの記述はTomcatのバージョンによって違うみたいなので要注意。
下記の書き方は古いバージョンの書き方。
<ResourceParams name="jdbc/MySQL">
<parameter>
<name>username</name>
<value></value>
</parameter>
<parameter>
<name>password</name>
<value></value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>org.gjt.mm.mysql.Driver</value></parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql:///hellodb?useUnicode=true&characterEncoding=SJIS</value>
</parameter>
</ResourceParams>

今回行った書き方が新しいバージョンの書き方。正確にどのバージョンからは調べてないです・・
ちなみに、5.5系のリファレンス引用すると、
「http://jakarta.apache.org/tomcat/tomcat-5.5-doc/jndi-datasource-examples-howto.html」

<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource" username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/javatest?autoReconnect=true"/>

となってます。