JavaでHello World
Google
  HOME  |  基礎  |  掲示板  |  ツール |  書籍  |  デザインパターン  |  リンク  |  フィードバック
JavaでHello World > JDBC (データソース)編  
メニュー
Home
情報交換掲示板
ツールの部屋
Java関連の書籍
アプリケーション編
Swing編
Swing(イベント)編
Swing(Look&Feel)編
アプレット編
iアプリ編
サーブレット編
サーブレット(Linux)編
サーブレット(web.xml)編
サーブレット(セッション)編
サーブレット(クッキー)編
サーブレット(フィルタ)編
JSP編
JSP(ディレクティブ)編
JSP(アクション)編
JSP(スクリプト)編
JSP(オブジェクト)編
JSP(カスタムタグ)編
JSP(データベース)編
Apache + Tomcat編
Struts編
JDBC編
JDBC(データソース)編
JDBC(MySQL)編
JDBC(PostgreSQL)編
JDBC(トランザクション)編
JavaMail(SMTP)編
JavaMail(POP)編
JNI編
RMI編
RMI(アプレット)編
CORBA編
JNDI編
EJB編
EJB(Entity Bean)編
JMS(PTP)編
JMS(Pub/Sub)編
XML(SAX)編
XML(DOM)編
XSLT編
SOAP編
国際化編
国際化(タイムゾーン)編
国際化(通貨)編
リフレクション編
コレクション編
コレクション(Set)編
コレクション(List)編
コレクション(Map)編
スレッド編
正規表現編
アサーション編
ログ機能編
サウンド編
ファイル入出力編
URL編
ソケット編
データグラム編
HTTP
FTP編
jar編
javadoc編
Ant編
外部コマンド編
プロパティファイル編
システムプロパティ編
Eclipse編
  2003/2/11  田中宏和
JDBC (データソース)編
◆JDBCとは?
JDBCとはJavaからデータベースにアクセスするためのAPIです。
◆データソースとは?
データソース(DataSource)とはプログラムとデータベースへの接続との間のインターフェースで、データベースへの接続を取得するために使用されます。JDBC 2.0から使用できるようになりました。データソース(DataSource)を取得するには通常JNDIを使用します。データベースのドライバやURLの情報は外部の設定ファイルにもち、プログラム上ではデータソース名だけを使用してデータソース(DataSource)を取得します。そのため、他のサーバーへ移動した場合やデータベースが変わった場合でもコードを変更しなくてすむメリットがあります。また、データソース(DataSource)を使用することによってコネクションプーリングや分散トランザクションを行うことができるようになります。
◆DriverManagerとDataSource
Javaでデータベースに接続する方法は2種類あります。従来から使用されているDriverManagerを使った方法とJDBC 2.0から使用できるようになったDataSourceを使った方法の2つです。
■DriverManagerを使った方法
Class.forName("org.gjt.mm.mysql.Driver");
String url = "jdbc:mysql:///hellodb?useUnicode=true&characterEncoding=SJIS";
Connection con = DriverManager.getConnection(url);
■DataSourceを使った方法
InitialContext ic = new InitialContext();
DataSource ds = (DataSource)ic.lookup("java:comp/env/jdbc/MySQL");
Connection con = ds.getConnection();
 
取得できるのはどちらも同じConnectionオブジェクトです。DriverManagerも従来通り使用できますが、JNDIサービスが動いていてDataSourceを使用できる環境ではDataSourceを使用してデータベースに接続することが推奨されています。また、J2EE環境ではDataSourceを使用することになっています。
◆ここで作成するプログラム
データソースを利用するにはJNDIサービスが動いているサーバーが必要です。Tomcat 4にJNDIサービスの機能があるのでそれを利用したいと思います。ここではサーブレットでデータベースに接続してデータの取得、表示を行うプログラムを作成します。
◆ここでの環境
OS Windows XP
J2SE SDK 1.4.1_01
Tomcat 4.1.18
データベース MySQL (バージョン3.23.49)
◆Java実行環境の構築
アプリケーション編を参考にしてJava実行環境を構築してください。
◆Tomcatを使用可能にする
サーブレット編を参考にしてTomcatを使用可能にしてください。
◆自分のWEBアプリケーションの作成
サーブレット編を参考にして自分のWEBアプリケーションを作成してください。ここではjavahelloという名前のWEBアプリケーションを使用します。
◆データベースの用意
JDBC(MySQL)編を参考にして、データベースのインストール、データベースの起動、データベースの作成、テーブルの作成、データの追加を行ってください。
◆TomcatでMySQLのJDBCドライバを使用可能にする
mysql-connector-java-○.○-bin.jarファイルを[Tomcatのフォルダ]\common\lib の下にコピーしてください。
(メモ)
データソースを使用する場合、データベースへの接続はTomcatが行うのでJDBCドライバが入ったJARファイルは[Tomcatのフォルダ]\common\libに置きます。また、DriverManagerを使用してプログラムの中で接続する場合は[Tomcatのフォルダ]\shared\libまたは[WEBアプリケーションのフォルダ]\WEB-INF\libに置きます。
◆JNDIのリソースの設定
JNDIのリソースの設定は[Tomcatのフォルダ]\conf\server.xmlに記述します。<Host>〜</Host>の間に以下の行を入れます。Context要素がすでに記述してある場合はResource要素とResourceParams要素をContext要素の中に記述してください。
<Context path="/javahello" docBase="javahello" debug="0" reloadable="true">
  <Resource name="jdbc/MySQL" auth="Container" type="javax.sql.DataSource"/>
  <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&amp;characterEncoding=SJIS</value>
    </parameter>
  </ResourceParams>
</Context>
 
まずResource要素でリソースを定義します。その次にResourceParams要素でリソースで使用するパラメータを設定します。ここではユーザー名、パスワード、ドライバークラス名、データベースのURLを設定しています。
◆データベースに接続するサーブレットの作成
データソースを使用してデータベースに接続するサーブレットを作成します。データソースはJNDIルックアップで取得できます。ルックアップの引数には「java:comp/env/リソース名」を指定します。リソース名のところにはserver.xmlファイルに設定したリソース名を入れてください。
また、このルックアップの処理は多少時間がかかるのでサーブレットのinitメソッドで行っています。
InitialContext ic = new InitialContext();
ds = (DataSource)ic.lookup("java:comp/env/jdbc/MySQL");


データベースの接続を取得するにはDataSourceオブジェクトのgetConnectionメソッドを使用します。
con = ds.getConnection();
■ソースコード
HelloWorldDSServlet.java(ここからダウンロード)
package javahello;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import javax.naming.*;
import java.sql.*;
import javax.sql.*;


public class HelloWorldDSServlet extends HttpServlet {
  DataSource ds;

  // 初期化処理
  public void init() throws ServletException {
    try {
      // 初期コンテキストを取得
      InitialContext ic = new InitialContext();
      // ルックアップしてデータソースを取得
      ds = (DataSource)ic.lookup("java:comp/env/jdbc/MySQL");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  //HTTP GET リクエスト処理
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
                      throws ServletException, IOException {

    Connection con = null;
    Statement stmt = null;
    try {
      // データソースからConnectionを取得
      con = ds.getConnection();
      // Statementを取得
      stmt = con.createStatement();
      // 検索するSQL文を作成
      String sql = "SELECT * FROM HELLO_WORLD_TABLE";
      // クエリーを実行して結果セットを取得
      ResultSet rs = stmt.executeQuery(sql);


      // 表示
      response.setContentType("text/html; charset=Shift_JIS");
      PrintWriter out = response.getWriter();
      out.println("<html>");
      out.println("<head>");
      out.println("<title>データソースでDB接続</title>");
      out.println("</head>");
      out.println("<body>");
      out.println("<table border=\"1\">");
      out.println("<tr>");
      out.println("<th>NO</th>");
      out.println("<th>言語</th>");
      out.println("<th>メッセージ</th>");
      out.println("</tr>");
      // 検索された行数分ループ
      while(rs.next()){
        out.println("<tr>");
        out.println("<td>" + rs.getInt("NO") + "</td>");
        out.println("<td>" + rs.getString("LANGUAGE") + "</td>");
        out.println("<td>" + rs.getString("MESSAGE") + "</td>");
        out.println("</tr>");
      }
      out.println("</table>");
      out.println("</body>");
      out.println("</html>");
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        if (stmt!=null) {
          stmt.close();
        }
        if (con!=null) {
          con.close();
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
}
 
■コンパイル
コマンドプロンプト
C:\JavaHello\DS>javac HelloWorldDSServlet.java

C:\JavaHello\DS>

■クラスファイルのコピー
「HelloWorldDSServlet.class」ファイルを[Tomcatのフォルダ]\webapps\javahello\WEB-INF\classes\javahello の下にコピーしてください。
■表示
ブラウザで以下のURLを指定してください。
http://localhost:8080/javahello/servlet/javahello.HelloWorldDSServlet
おおお!データベースに接続できましたね!
 
◆コネクションプーリングの設定
プールする接続の最大値などの設定を行うことができます。server.xmlファイルのリソースのパラメータの指定のところに以下の青字の部分を追加することができます。パラメータの説明は下の「パラメータの説明」のところを参照してください。また、数値は環境に合わせて調整してください。
  <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&amp;characterEncoding=SJIS</value>
    </parameter>
    <parameter>
      <name>maxActive</name>
      <value>10</value>
    </parameter>
    <parameter>
      <name>maxIdle</name>
      <value>5</value>
    </parameter>
    <parameter>
      <name>maxWait</name>
      <value>10000</value>
    </parameter>
  </ResourceParams>
 
■利用不可能になった接続の再利用
上で設定した他に「removeAbandoned」、「removeAbandonedTimeout」、「logAbandoned」を指定することができます。これらはWEBアプリケーションが接続をcloseしなかった場合の問題を解決します。WEBアプリケーションが接続をcloseに失敗した場合に、その接続は再び使用することができなくなります。そのような利用不可能な接続がプールの最大値に達するとデータベースに接続できなくなってしまいます。そのような利用不可能になった接続を再利用できるようにするにはremoveAbandonedパラメーターをtrueに設定します。また、そのような問題が起きるのはプログラムのバグの場合が多いのでcloseに失敗した問題がどこで起きたかわかるようにlogAbandonedをtrueに設定してトレースログを出力することもできます。
■パラメータの説明(Tomcat 4)
パラメータ 説明
maxActive プールする接続の最大値を指定します。0を指定すると無制限になります。
maxIdle プールの中に保持する使用されていない接続の最大値を指定します。0を指定すると無制限になります。
maxWait プール内の接続が全て使用されている場合、接続が使用可能になるまで待つ時間をミリ秒単位で指定します。この時間が過ぎても接続が使用可能にならない場合は例外がスローされます。-1を指定すると無期限になります。
removeAbandoned 利用不可能な接続を再利用可能にする場合trueに設定します。規定値はfalseです。
removeAbandonedTimeout 利用不可能とみなすまでの時間を秒単位で指定します。規定値は300秒です。
logAbandoned 接続のcloseに失敗した場所をログに出力する場合にtrueに設定します。規定値はfalseです。
 
■関連
サーブレット編
JDBC(MySQL)編
■書籍
Java関連の書籍

 
  ネットで買えば断然お得!お買い物なら楽天市場
ツールの部屋 - Java関連の書籍 - デザインパターン - 情報交換掲示板 - HOME