月曜日, 6月 01, 2009

【Google App Engine】 JDOから直接SOAP、ATOM。それからDeep Copy このエントリーを含むはてなブックマーク


 Reflexを使ってJDOからSOAPに変換するサンプルとATOMに変換するサンプルを作ってみた。これらは Reflex Core Samples(2005年作成)をGAEに移植したものだ。

reflexworks




 O/Rマッパに慣れている方は不思議に思うかもしれないが、ReflexではEntityの構造がXMLの構造になるため、DXOのような詰め替えが必要なく、またマッピング用定義ファイル等も必要ない。
 下図は実際の保存イメージである。SOAPやATOMのデータはReflexによりJDO Entityに変換され、1Entityが1TableのようなイメージでDatastoreに保存される。Entityはオブジェクトの形で保存されるが、各Entityは別々に管理されており、Tableのようにカラムとバリューによる表のイメージとなっていることがわかる。Entityどうしの関係は別途Keyによって紐ずけられているので別々に管理されていても大丈夫なのである。



Reflex Core Samplesを移植するにあたって、Reflex Core本体にも手を入れたので補足したいと思う。

com.google.appengine.api.datastore.Text型をサポート


 Datastoreに保存する際に、String型では500文字以上扱えないため、大きなサイズのものを扱う場合はText型を使用する必要がある。JDOにStringで定義していたプロパティをTextにすると大きなサイズでも保存できるようになる。ただしIndexは付かないので注意が必要である。サンプルではAtomのContentでTextを使用している。

同じスキーマのEntityを異なるものとして扱う

 実際に、ATOM Sampleを見ていただくとわかるが、Feed要素の子要素にはAuthorとEntryがあり、かつ、Entryの子要素にも同じスキーマのAuthorがある。AuthorはFeed要素の子要素、つまり、「1対多」の関係が既に定義されているので、Entry要素の子要素としては定義することができない。そこで、複数のパッケージ名を同じ名前空間に指定できるようにして、同じクラス名であってもパッケージ名が異なれば違う要素として扱えるようにした。例えば、List<foo>.SampleとList<bar>.Sampleは異なるEntityとして区別される。こうすることで、Datastoreには異なるEntityとして保存されるようになる。これは同じスキーマのテーブルを2つ持つことと同じような意味である。
 
EntityのDeep Copy

上記のように同じスキーマの複数のEntityがあると、すべてのプロパティをコピーできるようなDeep Copy機能が欲しくなる。
 同じスキーマであれば以下のようにすることでDeep Copyが簡単にできる。


// entryのAuthorをfeedのAuthorにDeepCopy
IResourceMapper mapper = new ResourceMapper("jp.reflexworks.atom.entry");
IResourceMapper mapper2 = new ResourceMapper("jp.reflexworks.atom.feed");
jp.reflexworks.atom.feed.Author author3 = (jp.reflexworks.atom.feed.Author) mapper2.fromXML(mapper.toXML(author));



<関連>

Entityとトランザクション
JDOから直接JSON、XML
AXIS2のデータバインディング能力
AJAX CRUDサンプルとJDO代替ライブラリ
Pagingをどうやって実現するか
RESTfulアプリのCRUDサンプル -Servlet編-
RESTfulアプリのCRUDサンプル -Modeling編-

0 件のコメント:

 
© 2006-2015 Virtual Technology
当サイトではGoogle Analyticsを使ってウェブサイトのトラフィック情報を収集しています。詳しくは、プライバシーポリシーを参照してください。