Servlet と JSP による Web アプリケーション(その 2)

Model を作ろう(その 3)

データを格納する器はできましたので、次は実際にデータベースにアクセスしてデータを操作するクラスを作ります。DAO(Database Access Object)と言われるものです。

まず最初にデータベースへのアクセス一般を制御するユーティリティクラスを作ります。

package jp.mydns.akanekodou.dao;

import javax.naming.*;
import javax.sql.DataSource;

public class DaoUtil {
    private DataSource source;
    private static DaoUtil inst = new DaoUtil();

    private DaoUtil() {
        source = createDataSource();
    }

    public static DataSource getSource() {
        return inst.source;
    }

    private DataSource createDataSource() {
        DataSource ds = null;

        try {
            Context ctx = new InitialContext();
            ds = (DataSource)ctx.lookup("java:comp/env/jdbc/myds");
        } catch(NamingException ne) {
            ne.printStackTrace();
        }

        return ds;
    }
}

これはまぁこう書くもんだと思っていただいていいです。詳しくいうと、これはシングルトンと言って、アプリケーション内で DaoUtil クラスのインスタンスをただ一つに限定するためにこのような書き方になってます。このようなクラスを用意しておいて、DaoUtil.getSource() で DataSource を取得することになります。

次に、顧客マスタテーブルにアクセスしてデータを操作するクラスを作ります。

package jp.mydns.akanekodou.dao;

import javax.sql.DataSource;
import java.sql.*;
import java.util.List;
import java.util.ArrayList;
import jp.mydns.akanekodou.model.*;

public class CustomerDAO {
    private static final String SQL = "SELECT * FROM 顧客マスタ";

    private DataSource source;

    public CustomerDAO() {
        source = DaoUtil.getSource();
    }

    public List<Customer> all() {
        List<Customer> list = new ArrayList<Customer>();

        Connection con = null;
        Statement stmt = null;
        ResultSet rs = null;

        try {
            con = source.getConnection();
            stmt = con.createStatement();
            rs = stmt.executeQuery(SQL);

            while(rs.next()) {
                list.add(getCustomer(rs));
            }
        } catch(SQLException se) {
            se.printStackTrace();
        } finally {
            try {
                if(rs != null) rs.close();
                if(stmt != null) stmt.close();
                if(con != null) con.close();
            } catch(SQLException se) {
            }
        }

        return list;
    }

    private Customer getCustomer(ResultSet rs) throws SQLException {
        Customer c = new Customer();

        c.setId(rs.getInt("顧客ID"));
        c.setName(rs.getString("顧客名"));
        c.setPhone(rs.getString("連絡先"));

        return c;
    }
}

今回はデータを全件取得するメソッドのみが用意されていますが、必要に応じて条件を指定してデータを取得するメソッドなども追加していけるので、柔軟な書き方と言えます。コンストラクタを見ればわかる通り、CustomerDAO クラスのインスタンスを生成した段階で CustomerDAO のプライベートメンバ変数である source 内に DataSource が格納されています。

Model を作ろう(おまけ)

さて、上記の方法で DataSource を取得するためには、Java のソースだけでは上手くいきません。別途プロジェクト内の WebContent/META-INF 直下に以下の内容で context.xml というファイルを作成する必要があります。

<?xml version="1.0" encoding="utf-8"?>
<Context>

  <Resource name="jdbc/myds" auth="Container" type="javax.sql.DataSource"
    maxActive="100" maxIdle="30" maxWait="10000"
    username="scott" password="tiger" driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/menudb" />

</Context>

以上で Model に関する部分は一通り終わりです。次回は View の作成をします。