幸せのちから

          平凡的世界
          看似平常實崎嶇
          成如容易卻艱辛

          Hibernateを使用したLiveCycle Data Service+Flexアプリケーション開発手順の紹介

          Hibernateを使用したLiveCycle Data Service+Flexアプリケーション開発手順の紹介

          河合 信敏氏

          NECソフト株式會社 勤務
          現在、Flex User Groupで、n-kawaiのハンドル名で精力的に活動中。

          データベースと 連攜するFlexアプリケーション開発では、アプリケーションサーバにLiveCycle Data Service ES(以後LCDSと記述します)を組み合わせるのが一般的かと思います。(他にもSeaserプロジェクトのS2Flexを利用するなどの選択肢もあり ます)

          この説明ではLCDSとHibernateを利用して、データベース連攜するFlexアプリケーション開発の一例を紹介します。

          必要ソフトウェア

          • FlexBuilder2もしくは3(labs.adobe.comで配布)
          • LiveCycle Data Service ES(無償のExpress Editionで良い)
          • Java SDK 5.0 (1.5.0_14)
          • Tomcat5.5.25
          • JOTM2.0.10
          • MySQL5.0.41
          • Eclipse3.3
          • Hibernate(LCDSにも付屬)
          • HibernateSychronizer3.1.9

          ※混亂を避けるため、Javaの開発はEclipseで、Flexの開発はFlexBuilderで操作するものとして説明を記述します。
          ※EclipseにはPleiadesプラグインを入れておくとメニュー等が日本語化されます。

          事前に必要な知識

          この文書では、次の経験があることを前提として記述していますが、基礎的な知識があれば十分です。

          • Javaでプログラムを作成したことがある
          • Eclipseを使用したことがある
          • Tomcatを使用したことがある
          • MySQLを使用したことがある
          • FlexBuilderでFlexアプリケーションを作成したことがある

          事前に用意するもの

          開発実行環境としては、Tomcat上にLCDS付屬のflex.warテンプレートがデプロイされている環境を用意してください。 TomcatにLCDS環境を用意する方法は、こちらのURLを參考にしてください。

          配布マテリアル(參考ソースコード) ( .zip , 13KB)

          この文書のライセンス

          Creative Commons License

          This Work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 2.1 Japan License. Using this work in advertising is allowed.

          1.データベース連攜機能の選択について

          LCDS上でデータベース連攜機能(Assemblerと呼びます)を作成するには、大きく分けて次の3つがあると思います。
          (1)JavaでAssemblerを自作する
          (2)Hibernate Assemblerを使用する
          (3)SQL Assemblerを使用する

          (1)はJavaコードを自前で作成します。既存のDBアクセスコードを流用したり、獨自のフレームワークを使用しているなどの場合では、それらを流用しつつDataServiceのfill()/sync()などのメソッドを実裝したAssemblerを 作成します。少しのコードを記述しなければなりませんが、データベース処理については自分で作成したコードを使用することができます。

          (2)はHibernateというオープンソースのO/Rマッピングを使います。基本的なデータアクセスではJavaコーディングをすることなく データベース連攜することができるため、開発工數が削減でき、その分をFlex開発に注力したり品質向上の為に工數を割り振ることができるかと思います。 この文書ではHibernate Assemblerを使用する手順の一例を紹介いたします。

          (3)はSQL文をLCDSの設定ファイルに記述することでデータベース連攜を実裝します。SQL文でデータアクセスを設計できる場合は、SQL Assemblerを選択してもよいかと思います。ここでは説明はしませんが、LCDS付屬のsamples.warのソースコードを參照すれば、使用方 法が理解できると思います。

          (2)と(3)については、いわゆるマスタメンテナンス系のシステム開発においては、DBアクセスのJavaコード作成が不要となるため、その分の 工數削減/生産性向上が見込めると思います。どちらを選択するかですが、プロジェクトにおいてデータ処理をSQL文で設計するのが適している場合には (3)を、 そうでないならば(2)を検討するのが、1つの目安かと思います。

          2.実習の流れ

          それでは、開発作業の流れを順に実習していきます。作業の流れは、次のようになります

          • データベースの作成
          • HibernateによるO/Rマッピング作成
          • LCDSの設定
          • Flexアプリケーションの作成

          実習では、図1のようなデータベース?テーブルを參照/更新する基本的なアプリケーションを作成します。

          図1
          図1

          また、システム構成としては、図2のようになります。

          図2
          図2

          サーバ側は、Hibernateの構成ファイルとマッピング、Data Transfer Object(DTO)を作成するだけですが、 プラグイン(HibernateSynchronizer)を使用することでさらに効率化が図れます。

          データベース?テーブルの作成

          テスト用のデータベース?テーブルを作成します。ここでは図3のような関係をもつテーブルを定義します。

          図3
          図3

          図3はClayデータベースモデリング(Eclipseプラグイン)を使用していますが、各自使い慣れたツールを使用して構いません。
          テーブル作成SQLは下記のようになります。それぞれMySQL Query Browserなどで実行してください。 (コード中のtestはMySQLのデフォルトスキーマです)

          ?グループテーブル作成

          CREATE TABLE test.LCDS_Group (
          group_id INTEGER NOT NULL
          , group_name VARCHAR(50)
          , PRIMARY KEY (group_id)
          ) CHARACTER SET utf8;

          ?ユーザテーブル作成

          CREATE TABLE test.LCDS_User (
          user_id INTEGER NOT NULL
          , user_name VARCHAR(50)
          , email VARCHAR(50)
          , group_id INTEGER
          , PRIMARY KEY (user_id)
          , INDEX (group_id)
          , CONSTRAINT FK_User_1 FOREIGN KEY (group_id)
          REFERENCES test.LCDS_Group (group_id)
          ) CHARACTER SET utf8;

          またテスト用のデータとして、下記のようなデータをそれぞれのテーブルに作成してください

          INSERT INTO `lcds_group` (`group_id`,`group_name`) VALUES 
          (1,'開発グループ'),
          (2,'営業グループ'),
          (3,'総務グループ');

          INSERT INTO `lcds_user` (`user_id`,`user_name`,`email`,`group_id`) VALUES
          (1001,'鈴木','suzuki@foo.com',1),
          (1002,'田中','tanaka@foo.com',1),
          (1003,'山本','yamamoto@foo.com',1),
          (2001,'佐藤','satou@foo.com',2),
          (2002,'斉藤','saitou@foo.com',2),
          (3001,'伊藤','itou@foo.com',3);

          以上でテストで使用するデータベース?テーブル作成ができました。

          4.Hibernateの定義

          次にHibernate定義を作成します。ここではシンプルなテーブルを使用するだけなので、定義ファイルを手で記述することも可能ですが、項目やテーブルの數が多くなると工數的な負擔も大きくなるので、 効率化のためHibernateSynchronizer(Eclipseプラグイン)を使用します。

          GUI操作となるので、若干記述が長くなりますが操作は1度試してみれば、簡単で効率的なことを実感できるかと思います。

          4-1.Eclipseを起動し、メニューから、[新規]-[プロジェクト]-[Javaプロジェクト]を選択してください。

          プロジェクト名は「LCDS_Lesson」とします。

          図4-1

          4-2.[次へ]を選択し、ライブラリで、外部JARにHibernateとMySQLのJDBCドライバを追加しておきます。

          <Hibernateライブラリ(LCDS付屬)>

          <MySQL JDBC Connector>

          図4-2

          4-3.作成したプロジェクトのsrcフォルダを右クリックして、[新規]-[その他...]を選択します。

          4-4.HibernateのHibernate構成ファイルを選択し、[次へ]をクリックします。

          図4-3

          4-5.データベース?タイプにMySQLを指定し、接続に図のような內容を指定します。

          ユーザ名/パスワードは各自のアカウント情報を指定してください。

          図4-4

          4-6.[終了]をクリックすると、hibernate.cfg.xmlが作成されます。念のためこのファイルをどこかにコピーしてください。

          4-7.再びsrcフォルダを右クリックし、[新規]-[パッケージ]を選びパッケージを作成してください。

          ここではパッケージ名は「test.lesson.lcds」とします。

          図4-5

          4-8.作成したパッケージフォルダを右クリックし、[新規]-[その他...]を選択します。

          4-9.HibernateのHibernateマッピング?ファイルを選択し、[次へ]をクリックします。

          図4-6

          4-10.パスワードを入力して[更新]をクリックするとデータベース上のテーブルが表示されるので、3章で作成したテーブルを選択し、パッケージには4-7で作成したパッケージ名を指定し、[終了]をクリックします。

          4-11.test.lesson.lcdsパッケージの配下にそれぞれのテーブルに対応したマッピングファイルが作成されていることを確認します(LcdsGroup.hbm.xml, LcdsUser.hbm.xml)。

          4-12.次にマッピングからDTOを生成します。

          LcdsGroup.hbm.xmlを右クリックし、[HibernateSynchronizer]- [ファイルの同期]を選択します。これでグループ用のDTOソースコードが生成されました。

          4-13.同じようにLcdsUser.hbm.xmlを右クリックして、[HibernateSynchronizer]-[ファイルの同期]を選択します。

          4-14.マッピング定義の一部を修正します。

          この実習で使用するテーブルは、プライマリキーの自動生成は必要ないので、LcdsGroup.hbm.xmlとLcdsUser.hbm.xmlをテキストエディタで開き、それぞれgeneratorタグをコメントアウトしてください。
          (例)<!--<generator class="sequence">-->

          4-15.次にLcdsGroup.hbm.xmlを右クリックし、[HibernateSynchronizer]-[マッピング參照の追加]を選択します。作成したマッピングが構成ファイルに追加されます。

          4-16.同じようにLcdsUser.hbm.xmlを右クリックして、[HibernateSynchronizer]-[マッピング參照の追加]を選択します。

          4-17.hibernate.cfg.xmlをテキストエディタで開いて內容を確認します。

          マッピング定義はsession-factoryの最後に追加されていますが、実は先頭のDOCTYPEタグが消えてしまいます。
          4-6.で作成したコピーから先頭のタグ行をコピーして復元ください。

          4-18.Hibernate構成ファイルに若干の編集をします。

          TomcatのコンソールでHibernateの動作を確認するためにhibernate.cfg.xmlの中の hibernate.show_sqlプロパティの値をtrueにしておいてください。

          4-19.LCDSで使用するfillメソッドに対応するクエリをマッピング定義に追加します。

          それぞれのマッピングファイルの最下行</hibernate-mapping>の前に、次の行を追加してください。

          ?LcdsGroup.hbm.xmlに追加する行
          <query name="all_group">From LcdsGroup</query>

          ?LcdsUser.hbm.xmlに追加する行
          <query name="all_user">From LcdsUser</query>

          4-20.グループのマッピングについては、ユーザ?テーブルとの関係を定義しているsetタグのinverse指定をfalseにしてください。

          ?LcdsGroup.hbm.xmlへの変更
          <set name="LcdsUsers" inverse="false">

          ※one-to-many、many-to-oneの関係についてのタグは、Windows+Eclipse+ HibernateSynchronizerではマッピングが生成されましたが、MacOSX+Eclipse+ HibernateSynchronizerでは生成されませんでした。
          私の環境の問題かどうか原因がわかりませんが、one-to-manyの関係をHibernte定義に反映したければ、この作業はWindows上で行った方が、良いかもしれません。

          4-21.すでにEclipseが自動的に、生成されたDTOのJavaコードをコンパイルしているので、Eclipseワークスペースのbin配下のファイルをTomcatのwebapps/flex/WEB-INF/classesにコピーします。

          testフォルダ
          hibernate.cfg.xml

          ここまでの操作で作成したHibernate構成ファイル、マッピングファイル、Javaソースコードは、添付マテリアルのsource/hibernateフォルダにあります。アカウント情報やURLなどは環境に合わせて変更してください。

          5.LCDSの設定

          5-1.Tomcatにデプロイしたflex.warテンプレートに、データサービス定義を追加します。

          編集対象ファイルは、webapps/flex/WEB-INF/flex/data-management-config.xmlにあります。

          5-2.チャネルの定義を追加します。

          <default-channels>
          <channel ref="my-rtmp"/>
          </default-channels>

          5-3.データサービスのdestinationを追加します。

          <destination id="hibernate-groupuser">
          <adapter ref="java-dao" />
          <properties>
          <use-transactions>true</use-transactions>
          <source>flex.data.assemblers.HibernateAssembler</source>
          <scope>application</scope>
          <metadata>
          <identity property="id"/>
          </metadata>
          <network>
          <session-timeout>20</session-timeout>
          <paging enabled="false" pageSize="10" />
          <throttle-inbound policy="ERROR" max-frequency="500"/>
          <throttle-outbound policy="REPLACE" max-frequency="500"/>
          </network>
          <server>
          <hibernate-entity>test.lesson.lcds.LcdsGroup</hibernate-entity>
          <fill-method>
          <name>fill</name>
          <params>java.util.List</params>
          </fill-method>
          <fill-configuration>
          <use-query-cache>false</use-query-cache>
          <allow-hql-queries>true</allow-hql-queries>
          </fill-configuration>
          </server>
          </properties>
          </destination>
          <destination id="hibernate-user">
          <adapter ref="java-dao" />
          <properties>
          <use-transactions>true</use-transactions>
          <source>flex.data.assemblers.HibernateAssembler</source>
          <scope>application</scope>
          <metadata>
          <identity property="id"/>
          </metadata>
          <network>
          <session-timeout>20</session-timeout>
          <paging enabled="false" pageSize="10" />
          <throttle-inbound policy="ERROR" max-frequency="500"/>
          <throttle-outbound policy="REPLACE" max-frequency="500"/>
          </network>
          <server>
          <hibernate-entity>test.lesson.lcds.LcdsUser</hibernate-entity>
          <fill-method>
          <name>fill</name>
          <params>java.util.List</params>
          </fill-method>
          <fill-configuration>
          <use-query-cache>false</use-query-cache>
          <allow-hql-queries>true</allow-hql-queries>
          </fill-configuration>
          </server>
          </properties>
          </destination>

          5-4.LCDS上で動作に必要なHibernateのJARファイルを追加します。

          LCDSインストールディレクトリにあるresources/hibernate配下の*.jarをTomcatのwebapps/flex/WEB-INF/libにコピーしてください。

          5-5.同じくMySQLのJDBCドライバを追加します。

          MySQLのJDBCドライバを、Tomcatのwebapps/flex/WEB-INF/libにコピーしてください。

          ここまでで、APサーバ(Tomcat)へのデプロイと設定作業は完了です。 Tomcatを起動してください。起動時にエラーがでるようであれば、エラーメッセージに応じて設定箇所を見直してください。

          ※LCDSのコンソールエラーは、webapps/flex/WEB-INF/classesにある commons-logging.propertiesの指定をNoOpLogから希望する書式の指定に変更することで、Tomcatコンソール (catalina.out)に出力されます。

          6.FLEXBUILDERでの作業

          6-1.新規にFlexプロジェクトを作成します。ここではプロジェクト名をLcds_GroupUserとします。

          図6-1

          6-2.[次へ]をクリックし、各自の環境に合わせてJ2EEサーバの情報を指定します。

          図6-2

          6-3.次にFlex側のDTOクラスを作成します。

          src フォルダを右クリックし、ActionSriptクラスを選択し、サーバのDTOクラス(Java)と同じ名前"LcdsGroup"と "LcdsUser"で作成してください。下記では最低限必要なリモートクラス指定とデータ変數を実裝しています。必要に応じて getter/setterを実裝してください。ソースコードファイルは付屬マテリアルにもあります。
          (LcdsGroup.as)

          package
          {
          import mx.collections.ArrayCollection;

          [Managed]
          [RemoteClass(alias="test.lesson.lcds.LcdsGroup")]
          public class LcdsGroup
          {
          public var id:int;
          public var groupName:String;
          public var lcdsUser:ArrayCollection;
          }
          }

          (LcdsUser.as)

          package
          {
          [Managed]
          [RemoteClass(alias="test.lesson.lcds.LcdsUser")]
          public class LcdsUser
          {
          public var id:int;
          public var userName:String;
          public var email:String;
          public var group:LCDSGroup;
          }
          }

          6-4.まず、Lcds_GroupUser.mxmlに次のコードを記述してください

          <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout=“horizontal" creationComplete="initApp()">
          <mx:Script>
          <![CDATA[
          import mx.data.DataService;
          import mx.data.events.*;
          import mx.rpc.events.*;
          import mx.collections.ArrayCollection;
          import mx.controls.Alert;
          [Bindable]
          private var acGroups:ArrayCollection;
          private var dsGroupUser:DataService;
          public function initApp():void {
          acGroups = new ArrayCollection();
          dsGroupUser = new DataService("hibernate-groupuser");
          dsGroupUser.autoCommit = false;
          dsGroupUser.addEventListener(ResultEvent.RESULT, resultHandler);
          dsGroupUser.addEventListener(FaultEvent.FAULT, faultHandler);
          dsGroupUser.addEventListener(DataConflictEvent.CONFLICT, conflictHandler);
          dsGroupUser.fill(acGroups, "all_group", []);
          }
          private function resultHandler(event:ResultEvent):void
          {
          trace("Data Service result return correct"); //BreakPointを設定
          }
          private function faultHandler(event:FaultEvent):void
          {
          Alert.show("Fault Error"); //BreakPointを設定
          }
          private function conflictHandler(event:DataConflictEvent):void
          {
          Alert.show("DataConflictError"); //BreakPointを設定
          }
          ]]>
          </mx:Script>
          </mx:Application>

          6-5.各イベントハンドラにブレークポイントを設定して、デバッグ実行してください。

          正常に実行できればresultHandler()のブレークポイントで停止し、acGroupsには図のようにデータが格納されていることを確認できます。

          図6-3

          6-6.ユーザ?テーブルについても同様です。

          これでデータは取得できたので、後はFlexでデータ表示?更新処理のユーザ?インタフェースを記述するだけです。
          シンプルな例としてのmxmlソースコードは、マテリアルにあります。

          7.補足

          7-1.データベース処理動作の確認

          Hibernate構成ファイルでshow_sqlにtrueを指定しているので、各データ操作でどのようなSQLが実行されているかをTomcatコンソールで確認することができます。

          7-2.アプリケーションの検証

          Hibernate構成ファイル?マッピング指定や性能についての検証は十分に行ってください。
          HibernateのマニュアルはこちらのURLで參照できます。

          古いバージョンですが、日本語のマニュアルはこちらのURLで參照できます。もっと新しい日本語マニュアルの掲載場所をご存知の方は、教えてください。

          この説明では觸れませんでしたがAPサーバのコネクションプーリング設定等(hibernate.properties)も考慮が必要です

          7-3.データアクセスをHibernateに「おまかせ」で良いのか?

          7-1でデータアクセス時にどのようなSQLが発行されているのかを參照することができますが、多少冗長なSQL処理をしているように見えます。こ の挙動については、システム要件として処理の最適化や性能が十分であるかや、開発期間などとのバランスを考えることになります。機能として性能條件が厳し くないものはHibernate Assemblerを使用して生産性向上を図り、SQLを最適化したい機能ではSQL AssemblerやJava Assemblerで実裝するなど、適宜使い分けるのが良いかもしれません。

          著者について

          河合 信敏氏
          FlexBuilder3の新機能により、基本機能が動作するサーバサイドとFlexのコードが自動生成されるようになりました。データベース連攜するFlexアプリケーション開発では、初期の開発工數について、より短縮できるようになったと思います。

          この文書の內容が、皆さまの作業効率化の助けになればと思います。

          posted on 2008-11-17 10:27 Lucky 閱讀(545) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2008年11月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          30123456

          導航

          隨筆分類(125)

          文章分類(5)

          日本語

          搜索

          積分與排名

          最新隨筆

          最新評論

          主站蜘蛛池模板: 辽中县| 永福县| 五峰| 元谋县| 珠海市| 双江| 广平县| 谷城县| 太湖县| 盘锦市| 丹东市| 搜索| 商洛市| 理塘县| 宜春市| 延寿县| 和平区| 石渠县| 乌兰察布市| 蒙城县| 台东县| 辰溪县| 二手房| 翁源县| 天气| 北宁市| 全椒县| 万年县| 色达县| 施秉县| 剑河县| 晴隆县| 新津县| 丹凤县| 本溪| 九寨沟县| 宜州市| 仙居县| 莱西市| 朝阳县| 巴彦淖尔市|