Edit Diff Annotate History
Upload
List
Recent
Alias
Top
Help
EOALCommunicateDB : Edit
Last updated: Fri Mar 30 22:07:46 +0900 2007
!データベースとの通信 アダプタレベルとデータベースレベル、2つレベルを行き来してデータベースにアクセスするといっても、実際にはどうやっているのでしょうか。 その前に、SQLを使ってデータベースと直接対話する場合を考えてみます。 この場合はシンプルで、データベースに接続してからSQLを発行するだけです。 トランザクション管理などデータ操作以外の処理もSQLやデータベース専用のコマンドで処理することができます。 EOFではこの処理を以下のグループに抽象化しています(かっこ内が対応するクラス)。 もっともこれは珍しいことではなく、多くのマッピングツールやネットワークアプリケーションで見られると思います。 * データベースへの接続、通信チャネル(EODatabaseChannel、EOAdaptorChannel) * トランザクション管理(EODatabaseContext、EOAdaptorContext) * データベース操作の組み立て(EODatabaseOperation、EOAdaptorOperation) * SQLの発行(EOSQLExpressionFactory、EOSQLExpression) この中でメインとなるのは、データのフェッチや保存を行うEODatabaseContextです。 EODatabaseContextは通信チャネル(EODatabaseChannel)を通してデータベースに接続します。 そのほかのクラスをどう使うかはフェッチ時と保存時で処理が異なります。 上記のクラスのうちAdaptorとつくものとSQLのクラスは抽象クラスです。 実際には各データベースに用意されたクラスが使われます(JDBCAdaptor、JDBCExpressionなど)。 WebObjects 5の場合、以下の各アダプタクラスをJDBCアダプタに置き換えて読んでください。 !フェッチ時の処理 フェッチ時はEODatabaseChannelにフェッチ命令を出すだけで、データベース操作を組み立てることはしません。 つまり、EODatabaseOperationとEOAdaptorOperationは使用されません。 まず、EODatabaseContextは空いている(問い合わせを実行中でない)通信チャネルを取得します。 EODatabaseChannelはEODatabaseContextから受け取ったEOFetchSpecificationを使ってSQL文を生成し、EOAdaptorChannelに実行させます。 続いてEOAdaptorChannelからフェッチしたデータ行を取り出してEODatabaseとEODatabaseContextにスナップショットを登録し、オブジェクトを生成してオブジェクトグラフに登録します。 図:フェッチ時の処理 <<dbcontext_fetching.png>> !保存時の処理 フェッチ時と同様、最初に通信チャネルを取得します。 次に変更のあるオブジェクトを調べ、データベース操作をEODatabaseOperationとして組み立てます。 続いてEODatabaseOperationからEOAdaptorOperationを生成します。 以上でデータベース操作の準備が整ったら、EOAdaptorContextがトランザクションを開始し、EOAdaptorChannelにデータベース操作を渡します。 EOAdaptorChannelは操作をSQL文に変換して実行します。 保存処理が正常に終了したらスナップショットとオブジェクトグラフを更新します。 図:保存時の処理 <<dbcontext_saving.png>> ※EODatabaseContextが複数ある場合やカスタムEODatabaseContextも考慮されるので保存時の処理はもっと複雑になりますが、ここでは簡略化しています。 !アダプタレベルとデータベースレベルのクラスの関係 これまでアダプタレベルとデータベースレベルのクラスは対応していると書いてきましたが、データベースレベルはアダプタレベルを単純に抽象化したものではありません。 保存時の処理を考えるとわかるように、それぞれのクラスが組み合わせて使われます。 以下に各クラスの役割を整理してみます。 ||EODatabaseContext||全般的にデータベースとの通信を制御する。 通信チャネルを用意し、データベース操作を組み立てて実行する。|| ||EODatabaseChannel||EOAdaptorChannelを生成し、データベースとの通信チャネルを開く。|| ||EODatabaseOperation||データベース操作(挿入、更新、削除)を表すオブジェクト。 スナップショットやグローバルIDの情報を持ち、データの変更内容を記録している。|| ||EOAdaptorContext||トランザクションを開始、終了する。|| ||EOAdaptorChannel||データベースと通信する。|| ||EOAdaptorOperation||データベース操作(ロック、ストアドプロシージャ、挿入、更新、削除)を表すオブジェクト。 挿入・更新するデータの内容や主キー値、データを特定する条件など、実際にデータベースを操作するための情報を持つ。|| 最終的にデータベースにアクセスするのは各アダプタクラスですが、それを制御するのがEODatabaseContextです。 EODatabaseContextはデータベース操作をEOAdaptorChannelに実行してもらわねばなりません。 EOAdaptorChannelを取得するためにEODatabaseChannelを使い、EOAdaptorChannelに渡すEOAdaptorOperationを生成するためにEODatabaseOperationを使います。 EOAdaptorContextを使ってトランザクションを開始したら、組み立てたEOAdaptorOperationをEOAdaptorChannelに渡します。 ちなみにEODatabaseChannelがフェッチ処理を行える(Operationが必要ない)のは、フェッチ条件であるEOFetchSpecificationの情報がそのままデータベース操作に使用できるからだと思います。 EOFetchSpecificationに含まれるエンティティ名やEOQualifier、EOSortOrderingsは、それぞれがSQL文に対応しています。