Date:  Wed, 10 Jan 2007 17:32:56 +0900
Subject:  【オブジェクト倶楽部: 2007-01号】
X-Mail-Count: 00176

       ┏━━━━━━━━━━━━━━━━━━━━━━━━━━■
       ┃                         ■┃
      ●┃● ● オ ブ ジ ェ ク ト 倶 楽 部   ■ ┃
       ┃                       ■  ┃
       ┗━━━━━━━━━━━━━━━━━━━━━━■━━━┛
                          No.170 2007/01/10

■ I N D E X
┃
┣【Topics】Developers Summit2007 で会いましょう!
┣【新年ご挨拶】
┣【プログラミング】Cayenneで始めるO/Rプログラミング[7]
┣【PF】アジャツール - Agileなツール紹介[18]
┗【アンケート】気になるシステム業界 ホントのところ

〇━━━━━━━━━━━━━━━━━━━━━━━━━━━T o p i c s━
 〇  Developers Summit2007 で会いましょう!
  〇 〇━━━━━━━━━━━━━ ━━・ 
    技術者コミュニティとの連携から生まれた総合ITコンファレンス
      ◇◆ Developers Summit 2007 (デブサミ2007)◆◇
  ◆2月14日(水)・15日(木)開催!◆会場:目黒雅叙園 ◆主催:翔泳社
       ▼無料の70セッションは完全事前登録制!お申込はこちら▼
          http://www.seshop.com/event/dev/2007/
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
オブジェクト倶楽部は、デブサミ2007を応援します。
コミュニティライブの「オブジェクト倶楽部流オブジェクト指向入門」、
角谷信太郎の「実践『From Java to Ruby』〜 血があつい鉄道ならば/走りぬけ
てゆく汽車はいつかは心臓を通るだろう 〜」どちらもきっと期待を裏切らない
こと間違いなし。お時間を作って、ぜひ会いに来てくださいね。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━1 s t ■━
■
┗【新年ご挨拶】

みなさんこんにちは。オブジェクト倶楽部事務局長の天野勝です。
新しい年を迎えました。このメールマガジンも、2003年に創刊してから、足掛
け5年になりました。ここまで続いているのも、このメルマガを購読されてい
る方、記事を執筆をしてくれる方、編集をしてくれる方のおかげです。この場
をお借りして感謝いたします。
本年も、執筆陣の熱い想いが届くように、情報発信に取り組んでいきます。
より多くの方に、なにかしらのきっかけや、場を提供できればと思っています。
これからもオブジェクト倶楽部にご期待ください。(天野勝)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━2 n d ■━
■
┗【プログラミング】Cayenneで始めるO/Rプログラミング[7]

このメルマガが発行されるであろう1/10の朝方、Macworld Conference & Expo 2007
でスティーブジョブスの基調講演があります。恐らく、そこで噂されている製
品の発表があるのではないかと。MacworldなんでiPodやiPhoneの話題まで踏み
込むかは微妙ですが、Leopardの発売日や、秘密の機能、インターフェースの変
更あたりが発表されるのではないかと思います。

さて、前回までは、関連先データを登録する際の手順を解説しました。
今回は、関連先を含めた複雑な検索の方法についてを解説します。
JDBCを使ってテーブルから検索する場合、関連先のオブジェクトを取得するに
は、テーブルジョインを使って検索できたResultSetから、複数のオブジェクト
を生成し、値をセットする必要がありました。テーブルの結合条件を考えたり、
結果を正しくマッピングしたりすることは、簡単な作業ではありませんでした。
しかし、O/Rプログラミングでは違います。検索条件の指定はより直感的で、オ
ブジェクトの関連さえわかれば、テーブルの結合条件を考える必要はありませ
ん。また、値のマッピングは最も得意とするところです。
まずは検証用データを準備しましょう。

ビデオテーブルに、以下のようなデータを登録しておきます。
ID  名前
----------------------------------
100 紅の豚
101 ガラスの艦隊 第3艦 「紅のバージニアよ、我に力を」
102 Soul Link
103 クロノクルセイド
104 マリア様がみてる「春」ファンディスク 1 紅薔薇
105 ストレンジドーン
106 GUNGRAVE
107 少年ジェット
108 東京ミュウミュウ
109 犬夜叉 紅蓮の蓬莱島
110 天地無用!GXP
111 紅三四郎
112 創竜伝 3 華麗なる代理人/摩天楼の紅竜王

会員テーブルに、以下のようなデータを登録しておきます。
ID   名前          生年月日
----------------------------------
1234 永和 太郎    1974-04-04
2222 福井 花子    1965-05-05
3333 東京 次郎    1986-06-06
4444 尾部 羅武    1990-10-10

貸出テーブルに、以下のようなデータを登録しておきます。
ビデオID 会員ID 貸出日     返却予定日
-----------------------------------------
100      1234   2007-01-03 2007-01-05
102      2222   2007-01-03 2007-01-07
106      2222   2007-01-03 2007-01-07
110      2222   2007-01-03 2007-01-07
103      4444   2007-01-04 2007-01-07
104      4444   2007-01-04 2007-01-07
109      4444   2007-01-04 2007-01-07

つまり、
・永和太郎さんが「紅の豚」を
・福井花子さんが「Soul Link」「GUNGRAVE」「天地無用!GXP」を
・尾部羅武さんが「クロノクルセイド」「マリア様がみてる「春」ファンディスク 1 紅薔薇」「犬夜叉 紅蓮 蓬莱島」
を、借りています。

この状況で、タイトルに「紅」が入っているビデオの貸出状況を検索してみま
しょう。JDBCでプログラミングした場合、以下のようなWHERE句が必要になるで
しょう。

... WHERE lending.videoId = video.id and lending.memberId = member.id and video.title like "%紅%"

このWHERE句で本来使いたい検索条件は、「video.title like "%紅%"」だけ
なのですが、取得したい値が別のテーブルにあるので、結合条件である
「lending.videoId = video.id and lending.memberId = member.id」を同じ
WHERE句の中で指定する必要があり、混乱の元になりがちです。

では、これをCayenneのコードで解説します。
今回はExtendsSearchというクラス名にしています。

public class ExtendsSearch {
      DataContext context = DataContext.createDataContext();
      public static void main(String[] args) throws IOException {
          ExtendsSearch search = new ExtendsSearch();
          search.main();
      }
      private void main() throws IOException {
          BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
          System.out.print("タイトル:");
          Expression exp = ExpressionFactory.likeExp(
                  Lending.TO_VIDEO_PROPERTY+"."+Video.TITLE_PROPERTY,
                  "%" + reader.readLine() + "%");
          SelectQuery query = new SelectQuery(Lending.class, exp);
          List<Lending> list = context.performQuery(query);
          System.out.println("会員名                 タイトル");
          for(Lending lending : list) {
              System.out.format("%-40s %s\n",
                      lending.getToMember().getName(), lending.getToVideo().getTitle());
          }
          reader.close();
      }
}

何はともあれ実行してみましょう。タイトルが問われたら「紅」と入力します。

・・・省略
タイトル:紅
・・・省略
INFO  QueryLogger: SELECT t0.rentDay, t0.returnDay, t0.memberId, t0.videoId FROM lending t0, video t1 WHERE t0.videoId = t1.id AND (t1.title LIKE ?) [bind: '%紅%'] - prepared in 32 ms.
INFO  QueryLogger: === returned 3 rows. - took 94 ms.
INFO  QueryLogger: +++ transaction committed.
会員名 タイトル
・・・省略A
永和 太郎                                    紅の豚
・・・省略B
尾部 羅武                                    マリア様がみてる「春」ファンディスク 1 紅薔薇
・・・省略C
尾部 羅武                                    犬夜叉 紅蓮の蓬莱島

すると、このようにタイトルに紅を含むビデオの貸出状況がわかります。関連
先の条件で検索する場合、検索条件はこれまでどおりExpressionFactory.likeExp
で作ることができます。
重要なのはその第一引数です。このサンプルでは、貸出状況を見たいので、検
索対象の主オブジェクトは貸出(Lending)です。
検索条件はビデオのタイトルですので、Lendingからの検索パスを記述する必要
があります。文字列で表すと「toVideo.title」という書き方が、ビデオのタイ
トルになります。toVideoはCayenneのモデラで割り当てた(自動的に付けられた)
関連名称です。

また、このサンプルでは実行時に省略A、省略B、省略Cとしたところで、会員を
別途検索しています。これは検索時には会員への関連が必要なかったのですが、
貸出状況を表示する際に会員名を使っているので、Cayenneが自動的に判断して
検索してくれているのです。
これはこれで便利なのですが、何度もSQL文を実行するのは効率的ではありませ
ん。Cayenneでは、このような関連先のデータを一度で取得したい場合、addPrefetch
メソッドを使うことで解決することができます。mainメソッドに追加してみま
しょう。

SelectQuery query = new SelectQuery(Lending.class, exp);
query.addPrefetch(Lending.TO_VIDEO_PROPERTY);    // 追加
query.addPrefetch(Lending.TO_MEMBER_PROPERTY);   // 追加
List<Lending> list = context.performQuery(query);

SelectQueryオブジェクトに、クエリ時にまとめて取得する関連先を設定してお
くだけでOKです。再度実行してみましょう。

・・・省略
タイトル:紅
・・・省略
INFO  QueryLogger: SELECT t0.rentDay, t0.returnDay, t0.memberId, t0.videoId FROM lending t0, video t1 WHERE t0.videoId = t1.id AND (t1.title LIKE ?) [bind: '%紅%'] - prepared in 15 ms.
INFO  QueryLogger: === returned 3 rows. - took 62 ms.
INFO  QueryLogger: SELECT t0.title, t0.id FROM video t0 WHERE t0.title LIKE ? [bind: '%紅%']
INFO  QueryLogger: === returned 6 rows. - took 0 ms.
INFO  QueryLogger: SELECT DISTINCT t0.birthday, t0.name, t0.id FROM member t0, lending t1, video t2WHERE t0.id = t1.memberId AND t1.videoId = t2.id AND (t2.title LIKE ?) [bind: '%紅%']
INFO  QueryLogger: === returned 2 rows. - took 0 ms.
INFO  QueryLogger: +++ transaction committed.
会員名 タイトル
永和 太郎                                    紅の豚
尾部 羅武                                    マリア様がみてる「春」ファンディスク 1 紅薔薇
尾部 羅武                                    犬夜叉 紅蓮の蓬莱島

すると、上記のように最初のクエリで全て検索が実行され、lending.getToMember().getName()
のタイミングでは検索が実行されていないことがわかると思います。

次に同じような考え方で、紅というタイトルを含むビデオを「借りている人」
を検索してみることにしましょう。つまり、検索対象をMemberにするというこ
とです。この場合mainメソッドは、以下のようになります。

      private void main() throws IOException {
          BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
          System.out.print("タイトル:");
          Expression exp = ExpressionFactory.likeExp(
                  Member.LENDING_ARRAY_PROPERTY+"."+Lending.TO_VIDEO_PROPERTY+"."+Video.TITLE_PROPERTY,
                  "%" + reader.readLine() + "%");
          SelectQuery query = new SelectQuery(Member.class, exp);
          query.addPrefetch(Member.LENDING_ARRAY_PROPERTY);
          query.addPrefetch(Member.LENDING_ARRAY_PROPERTY+"."+Lending.TO_VIDEO_PROPERTY);
          List<Member> list = context.performQuery(query);
          System.out.println("会員名                 タイトル");
          for(Member member : list) {
              boolean name = true;
              for(Lending lending : (List<Lending>)member.getLendingArray()) {
                  System.out.format("%-40s %s\n",
                          name?member.getName():"", lending.getToVideo().getTitle());
                  name = false;
              }
          }
          reader.close();
      }

会員から借りているビデオタイトルまで関連をたどると、会員->貸出->ビデオ
のようになります。これを関連名称で表現すると、「lendingArray.toVideo.title」
となります。会員から貸出は複数ありえるので、関連先Arrayという関連名にな
っています。SelectQuery#addPrefetchする場合も、同じようにいくつ先の関連
先でもドット(.)結合で表現することができます。では早速実行してみましょう。

・・・省略
タイトル:紅
・・・省略
INFO  QueryLogger: SELECT DISTINCT t0.birthday, t0.name, t0.id FROM member t0, lending t1, video t2WHERE t0.id = t1.memberId AND t1.videoId = t2.id AND (t2.title LIKE ?) [bind: '%紅%']
INFO  QueryLogger: === returned 2 rows. - took 47 ms.
INFO  QueryLogger: SELECT t0.rentDay, t0.returnDay, t0.memberId, t0.videoId FROM lending t0, video t1 WHERE t0.videoId = t1.id AND (t1.title LIKE ?) [bind: '%紅%']
INFO  QueryLogger: === returned 3 rows. - took 31 ms.
INFO  QueryLogger: SELECT t0.title, t0.id FROM video t0 WHERE t0.title LIKE ? [bind: '%紅%']
INFO  QueryLogger: === returned 6 rows. - took 15 ms.
INFO  QueryLogger: +++ transaction committed.
会員名                 タイトル
永和 太郎                              紅の豚
尾部 羅武                              マリア様がみてる「春」ファンディスク 1 紅薔薇
                                           犬夜叉 紅蓮の蓬莱島

ここで重要なのは、「尾部 羅武さんが借りているビデオ」に「クロノクルセ
イド」が入っていないことです。この検索モデルでは、タイトルに紅を含むビ
デオを借りている人なので、対象となった人からみた場合も、借りているビデ
オは紅を含むものだけになります。つまりタイトルに紅を含まない「クロノク
ルセイド」は検索対象にならないのです。

数回に渡って関連に関する技術を解説してきました。O/Rマッパーが単にDBの操
作を簡単にするだけでなく、オブジェクトの永続化に役立つということがわかっ
ていただけたのではないでしょうか?
次回は複合検索条件について解説する予定です。(きしだ)

_______________________________________________________________________
この記事への評価にご協力をお願いします。
URLをクリックして、「ご協力ありがとうございました」のメッセージがご使用
のブラウザに表示されれば投票完了です。
良かった:
http://www.ObjectClub.jp/community/object_ml/estimate?vol=E010-6&choice=0
普通:
http://www.ObjectClub.jp/community/object_ml/estimate?vol=E010-6&choice=1
イマイチ:
http://www.ObjectClub.jp/community/object_ml/estimate?vol=E010-6&choice=2

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━3 r d ■━
■
┗【PF】アジャツール - Agileなツール紹介[18]

● はじめに

あけましておめでとうございます。本年もよろしくお願い申し上げます。2007
年一発目のアジャツールは、かなり趣味の世界に入ってしまいますがご了承く
ださい。

この業界にいると、文書やメモをソフトウェア上で書いてしまうことが多いは
ずです。作業メモ、Todoリスト、日記、議事録などなど。筆者はテキストエディ
タ(Vim)を愛用していますが、アウトラインプロセッサや、ワード、Webアプリ
ケーションなど様々なソフトウェアがあり、読者の皆さんもそれぞれ使い分け
られていると思います。

筆者はここ2年で、手書きの頻度が以前に比べて飛躍的に上がりました。といっ
ても、主に自分だけで使う文書やメモ書きに限りますが、紙に向う時間を意図
的に増やしています。手書きを増やすきっかけになったのが、今回紹介する万
年筆です。

● 万年筆

万年筆は、毛細管現象を利用してペン軸に格納されたインクをペン先に供給し
て紙に書くという、仕組みのペンです。英語では「fountain pen(泉のペン)」
というように、インクがペンから湧きでてくるように、非常になめらかに書け
る点がポイントです。その一方で多くの欠点もあります。[*1]_
一般では1970年代までは広く使われてきましたが、それ以降現在に至るまでは
ボールペンにその座を明け渡したと言われています。最近ではマニアが使う高
級文具のイメージが強いかもしれません。

筆者もほんの数年前までは、万年筆など持ったこともありませんでしたし、欲
しいと思ったこともありませんでした。筆者はとても筆圧が低い、つまり字を
書く時にペンに力を入れて書かないために、ボールペンやシャーペンなどを使
うと、あまり綺麗に書けませんでした。そのため無理に筆圧をかけて書くわけ
ですが、そうするとすぐに疲れてしまうため、手書きがおっくうになってしま
うという「ネガティブサイクル」を構築してしまっていました。

しかし、あるきっかけで万年筆の存在、つまり低筆圧でも書けるペンというこ
とを知り、低価格帯の万年筆を入手し、その書き味に「一発」でまいってしまっ
たのです。万年筆できちんとペン先が調整されていると、文字を書くのにほと
んど力を入れる必要がありません。ペンの自重でペン先を紙にのせて、人がそ
のペン先の行く先をナビゲーションしてあげるだけでよいのです。こうなると
書くのが楽しくなり、必要以上に手書きの機会を作りはじめるという「ポジティ
ブサイクル」が回るようになるわけです。

筆者の知人でも、最近万年筆を使用する人が増えてきています。どの方も高級
文具のコレクションというよりも、むしろ実用的に「もっと気持よく書ける」
万年筆という点で惹かれているようです。一緒のチームだったある人は「万年
筆は心を豊かにする」とまで言っていました。

万年筆はその名の通り、一度使いはじめれば、インクの交換、ペン先の調整を
して長い間使い続けることのできる道具です。書いてインクがなくなれば使い
捨てのボールペンが当たり前の時代の中で、物の大切さを感じさせてくれる貴
重な存在なのです。

● 万年筆に学ぶこと

万年筆を使っていて気づいたことは、「書く」という行為が万年筆を介するこ
とで、「楽しく書く」に変換されてしまうということです。行為の結果は変わ
らないのですが、その過程を「楽しく」感じるかによって、行為そのものへの
モチベーションが180度変わってしまうのです。

そして、その「楽しさ」は必ずしも「効率的」ではありません。先にも取りあ
げた通り、万年筆は多くの欠点を抱えています。効率という「ものさし」でみ
た場合には、万年筆はあまり価値がないものと捉えられてしまいます。しかし、
別のものさしを使ってみると、まったく別の存在感がでてくるのです。物事の
価値は、ものさしによって大きく変ってしまうのです。

時代から一度はみすてられた万年筆が近年再び脚光を浴び、単なる高級文具マ
ニアのアイテムではない、身近な実用品として捉えられているそうです。今ま
での効率というものさしではなく、別のものさしを時代が求めているという一
つの現れではないでしょうか。人はひとつのものさしで物事を捉えてしまいが
ちです。
けれども、別のものさしでしか見えないことがあるということを、万年筆は筆
者に伝えてくれた気がします。

● 最後に

ここまで書いてみると、なぜこれが「アジャツールなのだ?」という疑問がわ
くかもしれません。アジャツールの定義に「アジャイルな人が使っているツー
ルである」というものがあります。私の回りのアジャイルな人々で万年筆を使
う人が増えてきたので、胸を張って「万年筆はアジャツールである」と認定し
たいと思います。 (懸田)

[*1] : http://ja.wikipedia.org/wiki/%E4%B8%87%E5%B9%B4%E7%AD%86#.E6.AC.A0.E7.82.B9
_______________________________________________________________________
この記事への評価にご協力をお願いします。
URLをクリックして、「ご協力ありがとうございました」のメッセージがご使用
のブラウザに表示されれば投票完了です。
良かった:
http://www.ObjectClub.jp/community/object_ml/estimate?vol=M002-18&choice=0
普通:
http://www.ObjectClub.jp/community/object_ml/estimate?vol=M002-18&choice=1
イマイチ:
http://www.ObjectClub.jp/community/object_ml/estimate?vol=M002-18&choice=2

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━4 t h ■━
■
┗【アンケート】気になるシステム業界 ホントのところ

今週は「2007年に伸ばしたいと思うこと」のホントのところ。年の初めには、
何かと心厳かに色々考えたりします。読者のみなさんはいかがでしょうか?さ
て、今回はオブラブメルマガ読者の皆さんが、2007年に1番伸ばしたいのはどん
なことでしょうか?

  どんどんやりましょう!見える化。
     http://www.ObjectClub.jp/special/kininaru/vote?vol=136&choice=0
  充実した仕事を!マネージメント能力。
     http://www.ObjectClub.jp/special/kininaru/vote?vol=136&choice=1
  益々伸ばそう!技術力。
     http://www.ObjectClub.jp/special/kininaru/vote?vol=136&choice=2
  いい人と仕事したいな!コミュニケーション力。
     http://www.ObjectClub.jp/special/kininaru/vote?vol=136&choice=3
  インプット重要!学習能力。
     http://www.ObjectClub.jp/special/kininaru/vote?vol=136&choice=4
  やっぱり、身長。
     http://www.ObjectClub.jp/special/kininaru/vote?vol=136&choice=5
  それは秘密です。
     http://www.ObjectClub.jp/special/kininaru/vote?vol=136&choice=6
  ちょっと語らせて!
     詳細をこのメールに返信ください!!

アンケート結果はオブジェクト倶楽部サイト上にて公開します。お楽しみに。
なお、前号「12月20日になにしてた?」の結果は公開中。ぜひご覧下さい。
⇒http://www.ObjectClub.jp/special/kininaru/vol135/PlonePopoll_results2
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━--■--●--■
■
┗編集後記

こんにちは、編集人です。新しい年が始まりました。皆さんどんな気持ちで新
年をお迎えですか?オブジェクト倶楽部は今年で5歳。ちょうどやんちゃでかわ
いい盛りですね。益々楽しく学びになることを手がけてゆきたいと思います。
今年もどうぞ、よろしくお願いいたします。

今週の強引な一言
***得手に帆を揚げる(ことわざ)***
得意とすることを発揮する好機が到来し、勇んでことに当たることのたとえ。
ただし、得意なことが解らないことには帆はずっと揚がらないままです。帆は
揚げるためにあるのです。風はいつか必ず吹きますよ!
(上田雅美)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━--■--●--■
● ご意見、ご感想は         ⇒このメールに返信ください
〇 配信中止、アドレス変更は ⇒http://www.ObjectClub.jp/community/object_ml/help/
〇 免責事項、過去の記事は   ⇒http://www.ObjectClub.jp/community/object_ml/
■ 発行:オブジェクト倶楽部 ⇒http://www.ObjectClub.jp/
■ 編集代表:平鍋  健児
Copyright (c)2003-2007 オブジェクト倶楽部. All Rights Reserved.
powered by Eiwa System Management, Inc.