2007/7/3 火曜日

DAOからSqlMapClientに作り変え

このエントリをはてなブックマークに追加DAOSqlMapClient篏紊のはてなブックマーク被リンク数
Filed under: ibatis — akky @ 19:11:48

昨日のエントリとも関連して
これまで、Webのサンプルを多く見つけられるver.1.0時代のDAO方式を使っていたけど、コネクション周りの挙動がすっきりしないので、iBATISのサイトにあるドキュメントを読んでいくと Ver2.0から使われるSqlMapClientの方素直に作れる予感。

半日かけてコーディング変更した甲斐はあり思うように動作している。でも、個人的にはDAO方式のコーディングが好みかな。実行するSQLをメソッド名で指定することで、コンパイル時にコーディングミスを発見できる嬉しさがある。パラメータに文字列として渡すのは実行してみないとミスに気づかないんだよね・・・。あっ。JUnitでしっかりテストすればいいんだけど、つい、億劫になってかかないんだよね。

JUnit。しっかり整備すれば強力なアイテムではあるけれども・・・・

2007/7/2 月曜日

トランザクション制御とDBへのコネクション

このエントリをはてなブックマークに追加潟吟激с喝九勝DB吾潟激с海里呂討淵屮奪マーク被リンク数
Filed under: ibatis — akky @ 13:42:04

ibatisを使っていると、DB(今回はMySQL)への接続が増える一方で減る気配がない。
# mysqladmin process
としてみるとアイドルな接続がモリモリ。

ibatisではjava.sql.Connection#Close()を明示的に実行する必要がないのは嬉しいけどDBへの接続が溜まり過ぎるのは困る。試行錯誤している中で手動でGCを行なうとMySQLへのコネクションが減った。finalyzeのタイミングか・・・。まあ、明示的にDBとの接続をcloseしないのであれば、DBから切断するタイミングはfinalyzeしかないよな。

それともう一つの理由。com.ibatis.dao.client#startTransaction()を行なっていないと、DAOからSQLを実行する都度、トランザクションを開始してSQLの実行完了後にcommitしている(ibatisが)。

当初はstartTransaction()の事には気づかなかったので、jvmのGC関連のパラメータを調整しても多少の延命はできても、JVMでのOut of memoryかDBでのtoo many connectionがおきてしまうので問題を解決できていない。
ふと、思い立って機能の単位にcom.ibatis.dao.client#startTransaction()とcom.ibatis.dao.client#endTransaction()を入れたことにより、ヒープの使用量とDBへの接続数が安定するようになった。GC関連のパラメータ調整よりもこちらの変更が的確だとおもうので、全体の完成度が上がってきた時点でもう一度GC関連のパラメータを調整する予定。

2007/6/25 月曜日

ibatisでクラスをシリアライズ化してDBに格納

このエントリをはてなブックマークに追加ibatisс鴻激≪ゃ阪DB主のはてなブックマーク被リンク数
Filed under: mysql, ibatis — akky @ 17:00:04

javaのクラスをシリアライズ化してMySQLのDBへ読み書きする方法

やり方

 ・DBにBLOB列を追加
 ・DTOにByte[]なシリアライズ化したオブジェクトを入れるフィールドを追加
 ・DTOにシリアライズ、デシリアライズのメソッドを追加

環境

 MySQL 5.0.41
java 1.5.03
ibatis ibatis-2.3.0677.jar,ibatis-dao-2.jar

テーブルの定義

mysql> desc WORD;
+-------------------+------------------+------+-----+---------+----------------+
| Field             | Type             | Null | Key | Default | Extra          |
+-------------------+------------------+------+-----+---------+----------------+
| WORD_ID           | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| WORD              | varchar(128)     | NO   |     |         |                |
| SERIALIZED_OBJECT | blob             | YES  |     | NULL    |                |
+-------------------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql>

DTO

ByteArray(Output|Input)Streamを使ってシリアライズ化(する|した)オブジェクトを読み書きする関係する部分だけを抜粋

    private byte[] serializedObject;
    /**
     * 指定されたインスタンスをシリアライズ化してINSERTorUPDATEを行なう準備をする
     * @param o シリアライズ化するクラスのインスタンス
     * @throws IOException 基本となる OutputStream が例外をスローした場合
     */
    public void setToSerialize(hogeClass o ) throws IOException{
      ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
      ObjectOutputStream objectOut = new ObjectOutputStream(byteStream);
      objectOut.writeObject(o);
      objectOut.close();
      this.serializedObject = byteStream.toByteArray();
    }
    /**
     * シリアライズ化されたオブジェクトをインスタンスに戻す。
     * @return デシリアライズしたオブジェクト
     * @throws IOException 基本となる OutputStream が例外をスローした場合
     * @throws ClassNotFoundException 基本となる OutputStream が例外をスローした場合
     */
    public hogeClass getDeSerialize() throws IOException, ClassNotFoundException{
      ObjectInputStream objectIn = new ObjectInputStream(new ByteArrayInputStream(this.serializedObject));
      hogeClass result = (hogeClass)objectIn.readObject();
      objectIn.close();
      return result;
    }

アプリ側

import java.io.IOException;
import java.io.Reader;
import java.io.Serializable;
import java.util.Iterator;
import com.ibatis.common.resources.Resources;
import com.ibatis.dao.client.DaoManager;
import com.ibatis.dao.client.DaoManagerBuilder;
public class SerialyzeTest  {
  /**
   * @param args
   */
  public static void main(String[] args) {
    // TODO 自動生成されたメソッド・スタブ
        Reader reader;
    try {
      classHoge t = new classHoge;
      t.addStartPosition(15);
      reader = Resources.getResourceAsReader("dao.xml");
          DaoManager daoManager =  DaoManagerBuilder.buildDaoManager(reader);
          Word out = new Word();
          WordDAO dao = (WordDAO) daoManager.getDao(WordDAO.class);
          dao.deleteByPrimaryKey(1);
          out.setWordId(1);
          out.setWord(t.getWord());
          out.setToSerialize(t);
          // 挿入実行
          dao.insert(out);
          // 挿入したレコードを検索してみる
          Word in = dao.selectByPrimaryKey(1);
          classHoge t2 = in.getDeSerialize();
          t2.methodFuga();
    } catch (Exception e) {
      // TODO 自動生成された catch ブロック
      e.printStackTrace();
    }
  }
}
次のページ »