1 00:00:00,560 --> 00:00:05,040 こんにちは。今回は Voyage を紹介します。 2 00:00:05,560 --> 00:00:07,880 NoSQL データベースのラッパーです。 3 00:00:08,120 --> 00:00:11,520 目標は、本物のアプリケーションを 構築することです。 4 00:00:11,680 --> 00:00:15,680 Voyage を使って TinyBlog のように Mongo データベースに 5 00:00:16,080 --> 00:00:19,200 オブジェクトを格納して、実サービスとして デプロイできるようになるでしょう。 6 00:00:19,400 --> 00:00:20,880 また、オブジェクトを格納するための 7 00:00:21,200 --> 00:00:23,680 簡単な方法もお見せしたいと思います。 8 00:00:24,080 --> 00:00:27,120 Voyage は簡単なソリューションです。 9 00:00:28,640 --> 00:00:30,320 まず、MongoDB とは何でしょうか? 10 00:00:30,760 --> 00:00:35,680 Mongo はドキュメント指向の 新しい NoSQL データベースです。 11 00:00:36,840 --> 00:00:40,280 強力な問い合わせ言語を持っています。 12 00:00:40,440 --> 00:00:44,440 Mongo はまた CouchDB や Riak に並んで 最も人気のあるデータベースの 1 つです。 13 00:00:44,600 --> 00:00:48,240 Mongo と Voyage を使いましょう。 14 00:00:48,480 --> 00:00:52,480 実際のところ、Voyage はマッパーです。 オブジェクトに対して プログラマに代わって 15 00:00:53,360 --> 00:00:56,680 MongoDB にほぼ自動的にマップします。 16 00:00:56,840 --> 00:00:58,880 Java で Hibernate を使ったことがあれば 17 00:00:59,040 --> 00:01:02,120 Voyage は MongoDB での Hibernate と同等です。 18 00:01:02,400 --> 00:01:03,960 ただし Voyage は Pharo 用に作られています。 19 00:01:05,120 --> 00:01:08,680 ここに Voyage の特徴を挙げています。 とても単純です。 20 00:01:08,840 --> 00:01:12,320 格納されたオブジェクトを読み込んだ時に 元のオブジェクトの同一性が保証されています。 21 00:01:13,000 --> 00:01:15,320 エラー処理も提供されています。 22 00:01:15,480 --> 00:01:18,840 そしてコネクションプールを実装しているので 23 00:01:19,000 --> 00:01:21,160 スピードも向上しています。 24 00:01:22,720 --> 00:01:25,360 簡単なところから始めましょう。 25 00:01:25,520 --> 00:01:28,640 最初に MongoRepositoryを作ります。 26 00:01:28,800 --> 00:01:31,520 これらの表現式を使います。 27 00:01:32,240 --> 00:01:35,680 Mongo データベースに アクセスしたいとします。 28 00:01:35,840 --> 00:01:37,920 Mongo は Pharo の外部で 管理されているわけですが 29 00:01:38,320 --> 00:01:41,880 プロトタイプする時にはよく 30 00:01:42,040 --> 00:01:44,440 Mongo データベースをオンメモリで使います。 31 00:01:44,600 --> 00:01:47,600 ここでは MongoMemoryRepository として参照されています。 32 00:01:48,040 --> 00:01:52,440 Mongo データベースは必要ありません。 まず最初に、アプリケーションをプロトタイプします。 33 00:01:53,040 --> 00:01:58,080 プロトタイプがちゃんと動くようになったら オンメモリのレポジトリを 34 00:01:58,360 --> 00:02:01,560 本物のレポジトリに切り替えて 外部にあるデータベースを使います。 35 00:02:01,720 --> 00:02:04,000 こうやって作っていきます。 36 00:02:07,400 --> 00:02:08,680 Mongo を説明するために 37 00:02:09,040 --> 00:02:13,240 とても単純なモデルを用意しました。 スーパーパワーを持ったスーパーヒーローがいて 38 00:02:13,680 --> 00:02:16,440 鎧や武器を持っています。 39 00:02:16,880 --> 00:02:21,440 このコースでお見せすることを使って 演習をすることができるでしょう。 40 00:02:21,600 --> 00:02:23,160 きっと助けになります。 41 00:02:23,560 --> 00:02:26,680 スーパーマンをスクリプティングすることを 楽しんでください。 42 00:02:27,280 --> 00:02:32,240 まず、どうやってヒーローとパワーを操るかを 見てみましょう。 43 00:02:33,400 --> 00:02:38,920 まず Hero クラスがあります。 Hero クラスには名前とレベルと能力があります。 44 00:02:39,880 --> 00:02:43,720 名前にはアクセサーとセッターがあります。 45 00:02:43,880 --> 00:02:45,640 レベルについても同様です。 46 00:02:46,000 --> 00:02:48,040 能力(power)は集合として管理します。 47 00:02:48,200 --> 00:02:53,000 能力がなければ空集合です。 48 00:02:53,600 --> 00:02:56,400 何か能力を加える時には それを集合に加えます。 49 00:02:56,560 --> 00:02:59,040 これがとても基本的な部分です。 50 00:03:00,720 --> 00:03:04,560 当面は能力には名前だけがあります。 51 00:03:05,720 --> 00:03:08,920 名前を書くこともできますし 書かないでおくこともできます。 52 00:03:10,000 --> 00:03:13,360 さて、ここでのポイントは ドメインクラスがデータベースに格納される 53 00:03:13,800 --> 00:03:17,000 ことをどうやって宣言するかです。 54 00:03:17,240 --> 00:03:22,600 ルートクラスという考え方を理解することが このデータベースの出発地点です。 55 00:03:23,160 --> 00:03:27,720 システムのどのクラスでも構いません。 ルートとして印を付けて 56 00:03:28,080 --> 00:03:32,280 isVoyageRoot というクラスメソッドがあれば。 (クラスメソッドですよ) 57 00:03:33,800 --> 00:03:38,640 Hero クラスの場合には isVoyageRoot は true を返します。 58 00:03:39,360 --> 00:03:43,400 この時点で Voyage は Hero を 59 00:03:43,800 --> 00:03:45,360 Mongo データベースに格納するとわかります。 60 00:03:46,640 --> 00:03:48,960 スパイダーマンをやってみましょう。 61 00:03:49,240 --> 00:03:51,880 名前は Spiderman で レベルは epic(最高)です。 62 00:03:52,240 --> 00:03:56,720 能力は、スパイダーマンの特殊技能ですが 彼の能力は強靭なこと、壁を登ること 63 00:03:57,160 --> 00:04:01,760 蜘蛛としての本能を持っているとされています。 64 00:04:02,440 --> 00:04:04,480 この情報を保存します。 65 00:04:04,880 --> 00:04:09,400 save は Voyage にこのスーパーヒーローを 66 00:04:09,560 --> 00:04:11,160 データベースに格納するように指示します。 67 00:04:11,400 --> 00:04:15,000 同じことをウルヴァリンと 彼の能力について行って 68 00:04:15,160 --> 00:04:16,600 そのデータを保存します。 69 00:04:16,880 --> 00:04:18,880 さて、Mongo データベースを見ると 70 00:04:19,040 --> 00:04:21,440 db.Hero.find すると 71 00:04:21,800 --> 00:04:21,840 スパイダーマンと 72 00:04:25,480 --> 00:04:27,280 彼の能力を見ることができるはずです。 73 00:04:27,640 --> 00:04:29,960 ここで気を付けてください。 74 00:04:30,360 --> 00:04:34,920 彼の能力はここに全て示されています。 75 00:04:35,360 --> 00:04:37,480 ウルヴァリンも同様です。 76 00:04:39,880 --> 00:04:43,640 これができたら、Pharo で沢山のことができます。 77 00:04:43,800 --> 00:04:48,080 詳しくは説明しませんが スーパーヒーロー全員を選んでくると 78 00:04:48,240 --> 00:04:51,320 スパイダーマンとウルヴァリンが得られます。 79 00:04:51,640 --> 00:04:54,960 スパイダーマンを見つけるように 言うこともできます。 80 00:04:55,240 --> 00:05:01,160 レベルが epic (最高) のスーパーヒーロー 全員を見つけてくるように言うこともできます。 81 00:05:02,080 --> 00:05:04,720 すると 2 人のスーパーヒーローが得られます。 82 00:05:06,560 --> 00:05:09,280 違う表現もできます。 83 00:05:09,440 --> 00:05:12,720 実際、Mongo データベースは 84 00:05:13,040 --> 00:05:16,160 JSON を扱うことができます。 つまり JSON を実行中に作って 85 00:05:16,440 --> 00:05:18,800 保管したり JSON 形式での問い合わせができます。 86 00:05:19,080 --> 00:05:21,600 どのスーパーヒーローが スパイダーマンという名前か 87 00:05:22,320 --> 00:05:24,560 知りたいとしましょう。 88 00:05:24,760 --> 00:05:29,760 JSON 形式で辞書として表現したので 1 つのエントリが得られます。 89 00:05:30,880 --> 00:05:33,440 同様に selectMany: することもできます。 90 00:05:33,680 --> 00:05:38,000 問い合わせを表現するのに最も簡単な 方法が何かによるわけですが 91 00:05:38,160 --> 00:05:40,640 それは今の所は大事ではありません。 92 00:05:40,960 --> 00:05:43,400 もっと高度な問い合わせもできます。 93 00:05:43,680 --> 00:05:46,280 ヒーローを全員選んだり 94 00:05:46,920 --> 00:05:51,280 あるいは 最高レベルのスーパーヒーローを 複数選ぶことができます。 95 00:05:51,440 --> 00:05:54,480 名前で昇順に並べることができます。 96 00:05:54,640 --> 00:05:58,400 リミットを 10 に設定した 0 ページ目から 開始することもできます。 97 00:05:58,560 --> 00:06:01,880 するとデータベースから区画ごとに 取り出すことができます。 98 00:06:03,120 --> 00:06:05,760 これらのことをしたい時には ドキュメンテーションを読んでください。 99 00:06:06,360 --> 00:06:10,280 他の操作もあります。 例えば、スーパーヒーローの数を数えるなど。 100 00:06:10,680 --> 00:06:14,160 ある特定の性質を持つものだけを数えることができます。 101 00:06:14,440 --> 00:06:18,240 削除することもできます。 全て削除したら、データベースが空になります。 102 00:06:18,560 --> 00:06:20,360 このコマンドには気を付けてください。 103 00:06:20,520 --> 00:06:23,680 ここで、1項目選択して それを削除することができます。 104 00:06:24,520 --> 00:06:26,960 このヒーローはデータベースから削除されます。 105 00:06:28,360 --> 00:06:31,000 これらの操作をすることができます。 106 00:06:31,880 --> 00:06:35,600 さて、MongoDB を使っていると 出てくる疑問があります。 107 00:06:35,760 --> 00:06:39,840 Mongo ではベースルートとは何でしょう? 108 00:06:40,280 --> 00:06:42,760 クラスはいつルートと定義されるのでしょう? 109 00:06:43,080 --> 00:06:46,640 答えは、問い合わせたいクラスが ベースルートです。 110 00:06:46,800 --> 00:06:48,200 それが第 1 のルールです。 111 00:06:48,320 --> 00:06:51,440 あるクラスをルートと定義するのは 112 00:06:51,600 --> 00:06:55,600 そのクラスの全てのオブジェクトに アクセスしたいからです。 113 00:06:55,880 --> 00:06:58,880 別の理由としては ルート間でオブジェクトを共有したい 114 00:06:59,200 --> 00:07:02,800 という場合です。 115 00:07:03,640 --> 00:07:06,800 Power を共有したい 116 00:07:07,240 --> 00:07:10,440 ヒーロー間で能力を共有できることを 明確にしたい場合には 117 00:07:11,000 --> 00:07:15,160 Power (能力) をルートとして定義します。 118 00:07:15,560 --> 00:07:16,760 これを見てください。 119 00:07:17,560 --> 00:07:21,560 この例では、Hero はルートです。 120 00:07:21,720 --> 00:07:24,240 そして Power もルートです。 121 00:07:24,520 --> 00:07:28,520 Voyage では、どんなクラスもルートとして 宣言することができます。 122 00:07:29,120 --> 00:07:31,160 やり方はこうです。 123 00:07:32,280 --> 00:07:37,040 Power クラスは isVoyageRoot となっています。 124 00:07:37,880 --> 00:07:42,040 さて、Fly(飛行)という能力を作って 125 00:07:42,400 --> 00:07:44,960 保存します。これでデータベースに格納されます。 126 00:07:45,920 --> 00:07:47,840 強靭(Super strength)も同じです。 127 00:07:48,000 --> 00:07:52,280 ここで Voyage に飛行能力を取り出すように 128 00:07:52,680 --> 00:07:55,520 問い合わせることができます。 129 00:07:55,760 --> 00:08:00,160 また、超人的な強靭さの能力も 取り出したい。 130 00:08:00,920 --> 00:08:03,240 そしてここで、スーパーマンを作ります。 131 00:08:03,640 --> 00:08:05,080 Voyage に伝えている意味は 132 00:08:06,840 --> 00:08:11,120 ここに 2 つの能力があって、(このヒーローは) システムに1つしかないものだから、それを保存する。 133 00:08:11,400 --> 00:08:15,280 基本的なスキーマが変更されるたびに 134 00:08:15,480 --> 00:08:18,720 データベースをリセットして 135 00:08:18,880 --> 00:08:22,240 ちゃんと動くようにします。 136 00:08:23,600 --> 00:08:26,880 ここでどうなっているかを見せます。 137 00:08:27,320 --> 00:08:30,520 スーパーマンの能力は 前と違う形で表現されています。 138 00:08:31,360 --> 00:08:35,640 能力はヒーローの中に埋め込まれていません。 能力への参照になっています。 139 00:08:36,640 --> 00:08:41,440 つまり、飛行能力を持つ他のヒーローがいる ということです。 140 00:08:42,160 --> 00:08:46,640 2 つの Power のインスタンスがあるのではなく 共有されています。 141 00:08:47,440 --> 00:08:51,920 つまり、ドメインによって、また それをどうモデル化するかによって 142 00:08:52,280 --> 00:08:54,320 ルートの定義は異なってきます。 143 00:08:54,480 --> 00:08:57,440 この単純な例で考え方を理解してください。 144 00:08:57,720 --> 00:09:01,240 実際、繰り返しますが ドメインルートを定義するのは 145 00:09:01,600 --> 00:09:07,040 それに対して問い合わせをしたり オブジェクトを共有する場合です。 146 00:09:09,560 --> 00:09:13,880 Voyage では関連は 147 00:09:14,320 --> 00:09:17,360 関係データベースでの外部キーと 同じように表現されています。 148 00:09:17,640 --> 00:09:21,640 Voyage はルートオブジェクトの循環参照を 自動的に扱うことができます。 149 00:09:21,840 --> 00:09:26,440 しかし気を付けてください。 Voyage は埋め込まれたオブジェクト間の 150 00:09:26,880 --> 00:09:29,600 循環参照はサポートしません。 151 00:09:31,240 --> 00:09:35,800 実験してみてください。 ルートであれば安全です。 152 00:09:36,320 --> 00:09:40,600 このコースでは、Mongo データベースに オブジェクトを格納することが 153 00:09:41,040 --> 00:09:43,160 とても簡単だということをお見せしました。 154 00:09:43,680 --> 00:09:48,120 もっと知りたい場合には Enterprise Pharo: a Web Perspective 155 00:09:48,280 --> 00:09:50,200 を読んでください。 この MOOC の資料に入っています。 156 00:09:50,600 --> 00:09:55,680 スーパーヒーローデータベースを構築する ちょっとしたチュートリアルを参照できます。 157 00:09:56,840 --> 00:09:58,200 それで全て学ぶことができます。