■ ORM(Object Relational Mapper)の機能

注、ここでは既存のORMの機能ではなく、ORMとして考えられる機能を取り上げている。

ここではORM の機能を取り上げる. いろいろなものが考えられるだろうが、まずORM の機能を次のように分類する.

  1. 本質的な機能.
  2. 付随的な機能.
  3. 付加的な機能.

本質的な機能とは、前章の主張展開から導きだされる機能であり、付随的な機能とは、、データベースプログラミングをする上で必然的に発生する仔細な(だが避けて通れない) 処理をカバーする機能、付加的な機能とは、これらの最低限の機能に加えてあれば便利な機能とした. この分類はいささか恣意的だが、ご了解いただきたい.

2.1 ORMの本質的な機能

本質的な機能として次のものを挙げておく.
  1. カラムとフィールドの対応
  2. 表形式とツリー構造の対応

○ カラムとフィールドの対応

オブジェクトとレコードが相互変換される. すなわちオブジェクトのフィールドがテーブルのカラムに反映され、カラムの値が読み込まれてフィールドに設定される.JDBC ベースのプログラミングであれば、この対応をアプリケーションプログラムで一つ一つ記述する.

一つのテーブルをとってみても、いくつものSQLがあり、それぞれのSQLの処理で、この対応をとるのは面倒である. カラムが追加になったりした時の修正も気を使う.

この対応を自動的に行ってくれたり、あるいは一個所記述するだけで、すべてに展開してくれると省力化効果が大きい. 安心感もある.自動的に対応をとることができるのは、カラム名とフィールド名が一致している時(あるいはある規則がある時) に限られるが、適用できる場合は便利である.

○ 表形式とツリー構造の対応 

一つのテーブルのみをSELECTすることもあるが、実務では多くの場合、複数のテーブルをJOIN する. なのでJOIN が処理できて、ORMは一人前であるとも言うことができる. 二つ挙げておきたい.

  1. (SQL を記述するよりも簡単に)JOIN のやり方を記述してSQL を生成する.
  2. 取得したResultSet を元にオブジェクトのツリーを生成する.

カラム・フィールドのマッピングがあるとしよう. それに加えてJOIN のやり方を記述すると、それに応じて(JOIN 用の)SQL を生成することができれば非常にありがたい.

ここでポイントは「SQL を記述するよりも簡単に」ということ. 同じ程度の複雑さであれば、いっそのこと慣れたSQL を記述したほうがよい. ツールとしての存在価値がない.

後者はマッピングとJOIN の仕方が記述してあれば、実行時に自動的にオブジェクトツリーを作るというものである. ツリーを作りオブジェクトのリファレンスを設定する.

Hibernate やiBATIS は自分でSQL(と同等のもの) を記述する上に、オブジェクトツリーの構造を別に記述することが必要なので、両者の整合性が取れない場合がある. これは問題.

さらに後者についてコメントすると、処理内容によっては、オブジェクトツリーに展開する必要はなく、すべてのカラムに対応するフィールドを持ったオブジェクトのリストや、複数の種類のオブジェクトのマトリックスに展開したほうが、便利な場合がある. なので、(オブジェクトツリーを生成したり、しなかったり) 両方の機能があった方がベターである.

2.2 付随的な機能

付随的な機能に属するものとしては、例えばResultSet のクローズとかエラー処理などが挙げられる.

「付随的」と「あまり大事ではない」という感じの形容詞をつけたが、プログラミング的には難しくはないが面倒であり、また忘れがちなものである.バグのある程度の部分は、このような処理を忘れていると言うような単純ミスが多いのも現実である.

Java ではオブジェクトのフリーを自動的にやってくれるようになり、C++では神経を擦り減らしていたことを気にしないでよくなったのと似ている.


2.3 付加的な機能

「本質的な機能」がORM間でそれなりに差があることも事実. だが、こちらはORM の付加価値を高める機能であり、ORM の使い勝手のかなりの部分が、この機能によっている. またORM の特徴がでるところでもある.

これに属する機能は多岐にわたるが、思いつくものを挙げていく.

○ 楽観ロック

楽観ロックは、他の利用者が同じレコードを書き換えたことを検知してエラー処理をするもの. そのために数値型あるいは時刻型のカラムを用意して、更新する時にレコードを取得した時と異なっていれば、他の利用者がレコードを書き換えたと認識する.

楽観ロックの一つの問題点は、同じテーブルを扱うすべてのロジックが楽観ロックを実装していないと、正しい処理ができないことである. なので、ORM が楽観ロックの機能を自動的に実装してくれれば抜けがなくなり、非常にありがたい.

○ 論理削除

論理削除とは、データを削除する場合に実際にレコードを削除するのではなく、論理削除フラグのカラムを設けて、それに値を設定することで、削除状態を表現する.

アプリケーションで削除処理を行うと論理削除フラグに値を設定する. レコードを検索する場合には、論理削除されたレコードを無視するために、論理削除フラグを条件に入れて検索する.

ORMは、このような処理を「このカラムが論理削除フラグ」と設定ファイルに記述するだけで行ってくれる.

注、この機能は重要だと思うがHibernateやiBATIS(MyBATIS)にはない。

○ 自動設定項目

レコードの作成・更新時刻、レコードの作成者・更新者などをレコードに記録することが行われている.多くの場合、これらのデータは問題があったときの調査のためのデータなので、すぐさまシステムが停止するようなことはないが、システムの信頼性という意味で重要である.

楽観ロックや論理削除と同じく難しいものではないが、関連するすべての個所で漏れなく行わなければならない. このハードルが高い.ORMで設定するだけで、上記のような項目が自動設定されるならば、非常に楽である.

○ キーの自動生成

レコードのキーを自動生成できるデータベースがある. またそのような機能がないデータベースがある.上記の機能の有無に拘わらず、ORMで自動生成する機能で、これを使えばデータベースに依存しないプログラミングをすることができる.

○ DBの相違の吸収

SQLはデータベースによって微妙な相違がある. 設定ファイルでSQL を生成する場合、使用するデータベースに適したSQL を生成してくれるとありがたい.

ただし、この機能は「キーの自動生成」と同じくORMにとしては、さほど重要ではないように感じる.

○ Entity の状態管理

Entity たるオブジェクトは、new されたり、レコードから読み込みまれ、修正や削除が行われる. 多くの場合、それほど複雑なものではないが、複雑な処理の中で状態管理が難しくなる場合がある.

ORM によっては、Entity の状態を自動管理してくれるものがある. するとアプリケーションによる管理は不要となる. INSERT/UPDATE/DELETEを区別せずに、例えばpersist というメソッドを呼び出せばテーブルに反映される.

○ その他

その他には、トランザクション管理やキャッシュ機能が考えられる.





==
・目次 - Java言語プログラミング入門
  http://blogs.yahoo.co.jp/artery2020/39975776.html
・目次 - ビジネスパーソンの常識と非常識
  http://blogs.yahoo.co.jp/artery2020/39728331.html
・目次 - 論理・発想・思考についての考察と鍛え方
  http://blogs.yahoo.co.jp/artery2020/39657784.html
==