S2DAOを使ってみる

S2DAOについて触れてるページって意外と少ない

 というわけで、使い始めるのに意外と苦労しました。なのでハマった所をメモ。
 環境は以下のとおり。

JavaTomcatの配置のメモは割愛

 タイトル通り。
 あと、この時点でWebアプリ用のプロジェクトを作っておきます。

  • ソースの配置場所 WEB-INF\src
  • libの配置場所 WEB-INF\lib

 jarを配置する場所が必要になるのがその理由です。

今回のmySQLの設定

 今回は下記の設定を想定します。

S2DAOを用意する

ファイルをダウンロードする

下記のURLからダウンロードします。

jarファイルを配置する

解凍して得られた下記のフォルダのファイルをすべてでWEB-INF\libに配置します。

設定ファイルの雛型を配置する

以下のファイルが設定ファイルの雛型として使用できるので、WEB-INF\srcに配置します。

設定ファイルを修正する

 j2ee-mysql.diconを修正します。修正箇所は一番上のcomponent name="xaDataSource"のところ。
 xaDataSourceは何箇所か記載されてますが、他はコメントアウトされているはず。
 下記は書き換え方の例です。

<component name="xaDataSource"
    class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
    <property name="driverClassName">
        "com.mysql.jdbc.Driver"
    </property>
    <property name="URL">
        "jdbc:mysql://localhost:3306/js"
    </property>
    <property name="user">"root"</property>
    <property name="password">"root"</property>
</component>

S2DAO以外のライブラリを用意する

ファイルをダウンロードする

 TomcatS2DAOを使うためには、他にもライブラリが要ります。
 Apache Geronimoに含まれているjarがその必要なファイルです。
 今回は下記のURLから「Geronimo 1.0 with Tomcat (zip)」をクリックして得られるファイルを使用しました。
 http://geronimo.apache.org/apache-geronimo-v10-release.html

ファイルを取り出す

解凍して得られた以下の二つのファイルが必要ですのでWEB-INF\libに配置します。

DAO、Bean、SQLを作る

 今回は下記のファイルを作成したことにします。内容については、http://s2dao.seasar.org/ja/s2dao.htmlを読めば把握できるはず。
 配置場所は3ファイルともにWEB-INF\src\com\jazzSearch\dao\programIdです。

DAO
package com.jazzSearch.dao.programId;
import java.util.List;
public interface JsA0010JS_M_TITLEDao {
    public Class BEAN = JsA0010JS_M_TITLEBean.class;
    public static final String findTitle_ARGS = "titleNo,titleName";
    
    public List findTitle(String titleNo, String titleName);
}
Bean
package com.jazzSearch.dao.programId;
import java.io.Serializable;
import java.util.Date;
public class JsA0010JS_M_TITLEBean implements Serializable{

    private static final long serialVersionUID = 1633632049080330008L;

    public static final String TABLE = "JS_M_TITLE";
    public static final String VERSION_NO_PROPERTY = "version";
    
    private String titleNo;
    private String titleName;
    private Integer version;
    
    public String getTitleName() {
        return titleName;
    }
    public void setTitleName(String titleName) {
        this.titleName = titleName;
    }
    public String getTitleNo() {
        return titleNo;
    }
    public void setTitleNo(String titleNo) {
        this.titleNo = titleNo;
    }
    public Integer getVersion() {
        return version;
    }
    public void setVersion(Integer version) {
        this.version = version;
    }
}
SQL
SELECT
    TITLE_NO,
    TITLE_NAME,
    VERSION
FROM JS_M_TITLE
/*BEGIN*/WHERE
    /*IF titleNo != null*/ TITLE_NO LIKE /*titleNo*/'000001'/*END*/
    /*IF titleName != null*/AND TITLE_NAME LIKE /*titleName*/'CD_A'/*END*/
/*END*/
ORDER BY
    TITLE_NAME

アプリ固有のdiconファイルを作成する

 名前は任意です。

 ここではsearch_jazz.diconという名前で作成します。配置場所は、WEB-INF\srcです。

<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN"
"http://www.seasar.org/dtd/components.dtd">
<components namespace="dao">
    <include path="dao-mysql.dicon"/>
    <component name="JsA0010JS_M_TITLEDao" class="com.jazzSearch.dao.programId.JsA0010JS_M_TITLEDao">
        <aspect>interceptor</aspect>
    </component>
</components>

SQLを発行するクラスを用意する

 Strutsのアクションクラスにたとえば下記のような感じに書きます。
 DBにヒットするデータを置いておけば、デバッガで値を覗くとなにか取得できたりしてるはずです。

package com.jazzSearch.JsA;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;

import com.jazzSearch.dao.programId.JsA0010JS_M_TITLEBean;
import com.jazzSearch.dao.programId.JsA0010JS_M_TITLEDao;


public class JsA0010SearchAction extends Action {
    @Override
    @SuppressWarnings("unchecked")
    public ActionForward execute(ActionMapping map, ActionForm actionForm,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
        
        S2Container container = S2ContainerFactory.create("search_jazz.dicon");
        container.init();
        try {
            
            JsA0010JS_M_TITLEDao dao = (JsA0010JS_M_TITLEDao) container.getComponent(JsA0010JS_M_TITLEDao.class);
            List<JsA0010JS_M_TITLEBean> titleBeanList = null;

            try{
                //データ取得を行います。
                titleBeanList = dao.findTitle(titleNoCondition, titleNameCondition);
                
            }catch(org.seasar.framework.exception.SQLRuntimeException e){
                //DBとの通信時に失敗した場合の処理
            }
            
        }finally {
            container.destroy();
        }

        return map.findForward("default");
    }
}

(番外)DELETEなどの場合

 今回用意したDAOにはDELETEメソッドは存在しませんが、DELETEなんかを行うときはTransactionManagerを使う必要があります。
 TransactionManagerを使う際はこんな感じに書くよ、という例です。

package com.jazzSearch.JsA;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.transaction.TransactionManager;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.seasar.extension.jta.TransactionManagerImpl;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;

import com.jazzSearch.dao.table.JS_M_TITLEBean;
import com.jazzSearch.dao.table.JS_M_TITLEDao;
public class JsA0020DeleteAction extends Action {
    @Override
    @SuppressWarnings("unchecked")
    public ActionForward execute(ActionMapping map, ActionForm actionForm,
            HttpServletRequest request, HttpServletResponse response) throws Exception {

        S2Container container = S2ContainerFactory.create("search_jazz.dicon");
        try {
            container.init();

            //DBアクセス用のオブジェクトを生成します。
            TransactionManager transactionManager =
                (TransactionManagerImpl) container.getComponent("transactionManager");

            JS_M_TITLEDao mTitleDao = (JS_M_TITLEDao) container.getComponent(JS_M_TITLEDao.class);
            try{
                int cnt=0;
                transactionManager.begin();
                
                // タイトルマスタテーブルについて更新対象のデータを取得します。
                JS_M_TITLEBean mTitleBean = mTitleDao.find("1");
                if(mTitleBean == null){
                    //データの取得に失敗した場合は、続行が不可能であるためエラーメッセージを表示します。
                    transactionManager.rollback();

                    //DBとの通信時に失敗した場合のエラーメッセージの表示をこの辺に記載する。
                    return map.findForward("default");
                }
                
                //DBからレコードを削除します。
                cnt = mTitleDao.delete(mTitleBean);
                if(cnt <=0){
                    //データの削除に失敗した場合は、続行が不可能であるためエラーメッセージを表示します。
                    transactionManager.rollback();

                    //DBとの通信時に失敗した場合のエラーメッセージの表示をこの辺に記載する。
                    return map.findForward("default");
                }

                //処理が成功したたのでコミットします。
                transactionManager.commit();
                
            }catch(org.seasar.framework.exception.SQLRuntimeException e){
                transactionManager.rollback();

                //DBとの通信時に失敗した場合のエラーメッセージの表示をこの辺に記載する。
            }catch (Exception e) {
                //何らかの事情で例外が発生した場合には、ロールバックします。
                transactionManager.rollback();
                throw e;
            }
            
        }finally {
            container.destroy();
        }

        return map.findForward("default");
    }
}

最後に

 知っていればどうということ無いことばかりなのですが、気づくのに苦労しました……。
 一番はまったのは、Apache Geronimoに含まれているjarがないとTomcatから満足にS2DAOが使えないというところ。