Home > Tags > iBATIS

iBATIS

iBATISのSqlMapConfig.xmlについて

SqlMapConfig.xmlの設定を書いておきます。
正直、コネクションプーリングとか遅延ローディングだとかよく分からなかったので、そこらへんはとりあえずデフォルト設定にしておいたほうがいいかも。
分かるようになったら更新します。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
        "http://www.ibatis.com/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

    <!--
        sqlMapClientの最適化を行う(この<settings>エレメントは任意)
        maxRequests : 一度にSQLを実行するスレッドの最大数
                    (maxRequests > maxTransactions*10)
        maxSessions : 一時にアクティブになることができるセッション数
                    (maxTransactions < maxRequests < maxRequests)
        maxTransactions : 一度にSqlMapClient.startTransaction()に入ることができるスレッドの最大数
                        (maxTransactions < maxSessions && maxTransactions << maxRequests)
        cacheModelsEnabled : キャッシュを有効にするかどうか
        lazyLoadingEnabled : 遅延ローディングを有効にするかどうか
        enhancementEnabled : lazyLoadingの拡張?
        useStatementNamespaces : prepared statementsのローカルキャッシュを使用するかどうか
        defaultStatementTimeout : ?よくわからない
        classInfoCacheEnabled : キャッシュされたクラスを使用するかどうか
        statementCachingEnabled : prepared statementsのローカルキャッシュを使用するかどうか

        ちなみに以下の値はすべてデフォルト値です。
    -->
    <settings
        maxRequests="512"
        maxSessions="128"
        maxTransactions="32"
        cacheModelsEnabled="true"
        lazyLoadingEnabled="true"
        enhancementEnabled="true"
        useStatementNamespaces="false"
        classInfoCacheEnabled="true"
        statementCachingEnabled="true"
    />

    <!--
        トランザクション管理サービスの設定
    -->
    <transactionManager type="JDBC">
        <dataSource type="SIMPLE">
            <property name="JDBC.Driver" value="org.postgresql.Driver" />
            <property name="JDBC.ConnectionURL" value="jdbc:postgresql://localhost:5432/sampledb" />
            <property name="JDBC.Username" value="postgres" />
            <property name="JDBC.Password" value="postgres" />
            <property name="JDBC.DefaultAutoCommit" value="false" />
            <!-- コネクションプーリング(はっきりいってよく分からない部分なので書かないでおいたほうが無難かも。。) -->
            <property name="Pool.MaximumActiveConnections" value="10" />
            <property name="Pool.MaximumIdleConnections" value="5" />
            <property name="Pool.MaximumCheckoutTime" value="120000" />
            <property name="Pool.TimeToWait" value="10000" />
            <property name="Pool.PingQuery" value="select 1" />
            <property name="Pool.PingEnabled" value="false" />
            <property name="Pool.PingConnectionsOlderThan" value="0" />
            <property name="Pool.PingConnectionsNotUsedFor" value="0" />
        </dataSource>
    </transactionManager>

    <!-- sqlMapファイルの参照 -->
    <sqlMap resource="ibatis/dao/user.SqlMap.xml" />
</sqlMapConfig>

参考

iBATISでトランザクションする

iBATISのデフォルト設定だと自動コミットモードになっていて、細かなトランザクション処理ができません。なので、iBATISでトランザクションをできるようにしてみる。
設定・構成等はiBATIS入門と同じです。

自動コミットモードの解除

まずSqlMapConfig.xmlを編集して、自動コミットモードを解除しておきます。
大事なのは、「<property name=”JDBC.DefaultAutoCommit” value=”false” />」です。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
        "http://www.ibatis.com/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
    <!-- DB接続設定 -->
    <transactionManager type="JDBC">
        <dataSource type="SIMPLE">
            <property name="JDBC.Driver" value="org.postgresql.Driver" />
            <property name="JDBC.ConnectionURL" value="jdbc:postgresql://localhost:5432/sampledb" />
            <property name="JDBC.Username" value="postgres" />
            <property name="JDBC.Password" value="postgres" />
            <property name="JDBC.DefaultAutoCommit" value="false" />
        </dataSource>
    </transactionManager>

    <!-- sqlMapファイルの参照 -->
    <sqlMap resource="ibatis/dao/user.SqlMap.xml" />
</sqlMapConfig>

実際に動かしてみる

sqlMap.startTransaction()でトランザクションを開始して、sqlMap.commitTransaction()でコミットする。
正常・異常終了に関わらずfinallyでsqlMap.endTransaction()をする。
トランザクション処理を行う場合はこのパターンが定型だと思われる。

package ibatis;

import ibatis.dto.User;
import com.ibatis.sqlmap.client.SqlMapClient;
import java.sql.SQLException;

public class Sample {

    public static void main(String[] args) {
        // SqlMapClientを生成
        SqlMapClient sqlMap = MyAppSqlConfig.getSqlMapInstance();

        try {
            // トランザクションを開始する
            sqlMap.startTransaction();

            // insert
            User user = new User();
            user.setId(4);
            user.setName("Tanaka");
            user.setAge(35);
            sqlMap.insert("insertUser", user);

            // delete
            sqlMap.delete("deleteUser", 1);

            // コミットする
            sqlMap.commitTransaction();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                // トランザクションを終了する
                // commitTransaction()まで行かず、エラーが発生した場合はロールバックを行う
                sqlMap.endTransaction();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

iBATIS入門

導入

iBATISのインストール

インストールといってもjarファイルをクラスパスに追加するだけです。
以前は以下のような3つのファイルに分かれてたみたいですが、今は1つに集約されてます。

  • ibatis-common-2.jar
  • ibatis-dao-2.jar
  • ibatis-sqlmap-2.jar

こんな感じ(/libフォルダに入ってます。)

  • ibatis-2.3.4.726.jar

http://ibatis.apache.org/ からダウンロード。

あと今回はDBにPostgreSQLを使用するので、PostgreSQLのJDBCドライバもクラスパスに追加しておく。
ちゃんとJDKのバージョンに対応したドライバを使うこと。詳しくはPostgreSQL JDBC ドライバを使用する時の注意点を参照。
http://jdbc.postgresql.org/ からダウンロード。

DBの準備

DBにはPostgreSQLを利用します。
サンプルとして以下のようなテーブルを作成(DB名はsampledbとしています)

id name age
1 Yoshida 23
2 Abe 34
3 Ogawa 17
CREATE TABLE users (
    id serial NOT NULL,
    name character varying(100),
    age integer,
    CONSTRAINT id PRIMARY KEY (id)
)

※ちなみにnameというのはPostgreSQLでは予約語らしいですが。。。

フォルダ構成

ちなみにフォルダ構成はこんな感じにしています。

iBATIS(フォルダ構成)

使ってみる

1. SqlMapConfigを作成する。

まずiBATIS用configファイルを記述します。
DB接続設定やマッピングファイルの参照を書いていきます。

SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
    "http://www.ibatis.com/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
    <!-- DB接続設定 -->
    <transactionManager type="JDBC">
        <dataSource type="SIMPLE">
            <property name="JDBC.Driver" value="org.postgresql.Driver"/>
            <property name="JDBC.ConnectionURL" value="jdbc:postgresql://localhost:5432/sampledb"/>
            <property name="JDBC.Username" value="postgres"/>
            <property name="JDBC.Password" value="postgres"/>
        </dataSource>
    </transactionManager>

    <!-- sqlMapファイルの参照 -->
    <sqlMap resource="ibatis/dao/user.SqlMap.xml" />
</sqlMapConfig>

2. SqlMapConfig.xmlを読み込むクラスを作成する。

DBアクセスがあるたびに毎回SqlMapConfig.xmlを直接読み込んでもいいんですけど、DBアクセスするたびにファイルを開いたりしてたら大変だよね、っていう話で一回だけ読み込んでインスタンスを作成・保持しておくということをしておきます。
こういうのをデザインパターンで「シングルトン(Singleton)」というらしいです。

MyAppSqlConfig.java

package ibatis;

import java.io.IOException;
import java.io.Reader;
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

/**
* SqlMapClientを返すクラス
*/
public class MyAppSqlConfig {
    private static SqlMapClient sqlMap;

    static {
        try {
            String resource = "SqlMapConfig.xml";
            //シングルトンとして利用
            if (sqlMap == null) {
                Reader reader = Resources.getResourceAsReader(resource);
                sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlMapClient getSqlMapInstance() {
        return sqlMap;
    }
}

3. DTOを作成する。

DBのテーブルに対応したDTOクラスを作成しておきます。

User.java

package ibatis.dto;

public class User {
    private int id;
    private String name;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

4. マッピングファイル(SQL Mapファイル)を作成する。

ここでJDBCだとDBアクセスのためのDAOクラスを作るんですが、iBATISではそれをマッピングファイルとしてXMLで記述します。

user.SqlMap.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
    "http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap namespace="User">
    <!-- SELECT -->
    <select id="getUser" parameterClass="Integer" resultClass="ibatis.dto.User">
        SELECT
            ID,
            NAME,
            AGE
        FROM
            USERS
        WHERE
            ID = #VALUE#
    </select>

    <!-- UPDATE -->
    <update id="updateUser" parameterClass="ibatis.dto.User">
        UPDATE USERS
        SET NAME = #name#
        <dynamic>
            <isNotEqual prepend="," compareValue="0" property="age">
                AGE = #age#
            </isNotEqual>
        </dynamic>
        WHERE id = #id#
    </update>

    <!-- DELETE -->
    <delete id="deleteUser" parameterClass="Integer">
        DELETE
        FROM USERS
        WHERE ID = #id#
    </delete>

    <!-- INSERT -->
    <insert id="insertUser" parameterClass="ibatis.dto.User">
        INSERT INTO USERS (
            ID,
            NAME,
            AGE
        ) VALUES (
            #id#,
            #name#,
            #age#
        )
    </insert>
</sqlMap>

5. 実際に動かしてみる。

動かしてみます。

Sample1.java

package ibatis;

import ibatis.dto.User;
import com.ibatis.sqlmap.client.SqlMapClient;
import java.sql.SQLException;

public class Sample1 {

    public static void main(String[] args) throws SQLException {
        // SqlMapClientを生成
        SqlMapClient sqlMap = MyAppSqlConfig.getSqlMapInstance();

        // SELECT
        User user = (User) sqlMap.queryForObject("getUser", 1);
        System.out.println(user.getId() + "\t" + user.getName());

        // UPDATE
        user.setId(2);
        user.setName("Yuzawa");
        user.setAge(27);
        sqlMap.update("updateUser", user);

        // INSERT
        user.setId(4);
        user.setName("Morita");
        user.setAge(30);
        sqlMap.insert("insertUser", user);

        // DELETE
        sqlMap.delete("deleteUser", 3);
    }
}

以上を実行すると、テーブルが以下のようになり、

id name age
1 Yoshida 23
2 Yuzawa 27
4 Morita 30

実行結果は以下のようになる。

1	Yoshida

参考

Home > Tags > iBATIS

Search
Feeds
Meta

Return to page top