O/Rマッピングは、従来の煩雑なデータベースに関する処理の記述をスマートにし、、柔軟なアプリケーションの構築を可能にします。本連載ではオープンソースのO/Rマッピングフレームワーク「Hibernate」を用いてO/Rマッピングの基礎を解説します。そしてさらに、J2EEアプリケーションへの実践的な適用方法とそのメリットも紹介していきます。(編集局)
Javaを使ってリレーショナルデータベースを扱うアプリケーションを構築した経験があれば、データアクセスを行う際に発生する作業の煩雑さに覚えがあることでしょう。例えば以下のような作業を面倒だと感じたことはないでしょうか。
これらは、アプリケーション構築の本来の目的やアプリケーションの主要な機能の実装とは別に手間の掛かる作業です。また、この面倒なコーディングが時としてアプリケーションの品質に大きく影響を及ぼすこともあります。テーブルカラムを取り違えてしまうなどの気が付きにくいミスを生みやすい大変厄介な作業だからです。さらに次のような経験はないでしょうか。
実際の開発現場ではデータベーススキーマがしばしば変更されます。このデータベーススキーマの変更はアプリケーション全体に影響し、多くの修正作業が発生することになります。このような問題や煩雑な処理から開発者を解放し、リレーショナルデータベースのレコードをオブジェクトとして直感的に扱えるようにするための仕組みを提供するのがO/Rマッピングです。
O/Rマッピング(=Object / Relational Mappingの略称でORMと略されることもあります)とは、オブジェクト指向言語で扱う「オブジェクト」と「リレーショナルデータベース(RDB)のレコード」をマッピング(対応付け)することです。アプリケーションにO/Rマッピングを導入することで、オブジェクトへのデータ取得やオブジェクトデータの永続化といった処理を透過的に行うことができるようになります。またO/Rマッピングはプログラミングでのデータベース操作にかかわる煩雑な作業を軽減し、拡張性・柔軟性を持ったアプリケーションの構築をサポートします。
O/Rマッピングの機能は、O/Rマッピングフレームワーク製品によって提供されます。フレームワークには商用製品とオープンソースがありますが、本連載では誰もが入手して評価できるオープンソースの「Hibernate」を例に用います。
ここまでのまとめ:「O/Rマッピングとは?」
O/Rマッピングによってリレーショナルデータベースのレコードをオブジェクトとして直感的に扱えるようになり、リレーショナルデータベースにアクセスするプログラムを記述する際の煩雑な処理を軽減することができるようになります。
O/Rマッピングの具体的な説明に入る前に、O/Rマッピングという考え方が登場した背景について、どのような問題があったのか見ていきましょう。
オブジェクト指向言語でリレーショナルデータベースを扱う際に発生する処理の中でも最も煩わしい処理は、データモデルの設計思想の違いから発生するマッピング作業です。この問題はオブジェクト指向言語とリレーショナルデータベースの間の「インピーダンスミスマッチ」と呼ばれています。
「オブジェクト指向設計」と「リレーショナルデータベース設計」ではともに、それぞれの方法論と指向に基づいて、それぞれの技術基盤や役割に最適なデータモデルを設計します。
リレーショナルデータベース設計では、RDBの特性に合わせたデータモデルを定義します。主に正規化や非正規化といった方法を用いて、リレーショナルデータベースの検索や登録更新処理に最適なモデルを定義することができます。
対するオブジェクト指向設計では、現実世界のモデルに即したものとしてデータモデルを定義します。オブジェクト指向の方法論で構築されたモデルは現実世界に即しているだけに理解しやすく、またオブジェクトという柔軟な単位を持つことによって拡張や変更に強いモデルを構築することができます。しかし当然のことながらオブジェクト指向ではデータベースでの検索や更新の効率性といった懸案は全く考慮されていません。
◇リレーショナルデータベース設計
リレーショナルデータベースの検索や登録更新処理に最適なモデルを定義
◇オブジェクト指向設計
データモデルを現実世界のモデルに即したものとして定義
この2つの設計方針はどちらもそれぞれの要件に対応したモデルを定義するための優れた方法論であり、どちらが良い悪いというものではありません。リレーショナルデータベースのデータ設計時に下手にオブジェクト指向設計を用いたモデルを持ち込めば、以下のような不都合を招くことがあります。
リレーショナルデータベースは広く普及した実績の豊富な信頼性の高いシステムです。正しく設計されたリレーショナルデータベースのデータは、1つのアプリケーションで使われるだけでなくほかのアプリケーションでも利用されます。そのためリレーショナルデータベースに保存されたデータの寿命は、それを扱う個々の「アプリケーション」よりも長い場合があります。リレーショナルデータベースに対して無理にオブジェクト指向設計を持ち込むよりも、それぞれの最適な設計方法を共存させる方が得策といえるのではないでしょうか。
このように、設計思想の違いから「リレーショナルデータベースのデータ構造」と「オブジェクト指向言語のデータ構造」には、データモデル上のミスマッチが生じてしまいます。そこで表形式のデータをオブジェクト形式のデータに対応付けるマッピングコードを作成する必要が生じます。このマッピングコードを記述する作業はデータの構造によっては大変煩雑な作業になります。また単調なコードの繰り返しである場合が多く、気が付きにくいバグを埋め込んでしまう危険性が高いコーディングであるともいえます。
リレーショナルデータベースを操作するための標準言語として「SQL」があります。このSQLは「非オブジェクト指向」の言語であり、「継承」や「カプセル化」といったオブジェクト指向のエッセンスは持ち合わせていません。そのため、オブジェクト指向言語によるプログラミングに非オブジェクト指向言語であるSQLが紛れ込んでしまうことによって、オブジェクト指向の柔軟性が損なわれてしまう可能性があります。
例えば図2「SQLベースのデータベース更新の作業」を参照してください。SQLを利用するプログラミングでは、あるオブジェクト内のデータをデータベースに保存するために、データをオブジェクトからいったん取り出してSQL文を組み立てる必要があります。この場合データベースカラムに変更があれば、データアクセスメソッドのSQL構築の実装を修正する必要があります。
これら「インピーダンスマッチ」と「非オブジェクト指向手続きによる柔軟性の阻害」がO/Rマッピング登場以前の大きな課題でした。
O/Rマッピングが誕生した背景を整理できたところで、次にO/Rマッピングのメリットについて具体的に見ていきます。
O/Rマッピングを利用してデータの保存を行うときのイメージを図3「O/Rマッピングによるデータベース更新の作業」に表しました。
O/Rマッピングを利用した場合、対象オブジェクトを「データベース更新メソッド」の引数に渡すだけで済み、SQLを組み立てるプログラムを記述する必要はありません。またデータベースのカラムに変更があった場合でも対応するデータクラスのフィールドを追加するだけでよく、保存手続きのロジックに大きな変更は発生しません。
次に、図4「O/Rマッピングによるデータの取得」としてO/Rマッピングでの検索処理を表しました。O/Rマッピングでの検索方法は個々の製品(フレームワーク)によって異なりますが、どんなO/Rマッピング製品でも検索結果としてはデータがマッピングされたオブジェクトインスタンスを取得できます。
このように、O/Rマッピングを利用することでプログラマはSQLを意識することなくデータベースにアクセスできるようになります。
しかしながら、O/Rマッピングを採用したからといってSQLを全く理解していなくてよいというものではありません。確かにO/Rマッピングによって「SQLレス」のデータベースアクセスを行うことは部分的には可能です。しかしながら、SQLはリレーショナルデータベースを扱ううえで最適な言語であり、データベースアクセスを行うシステムを構築する開発者にとって必要不可欠なものであることに変わりありません。
実際のO/Rマッピングフレームワークでは内部的にSQLを発行しており、パフォーマンスチューニングやデバッグを行う際には必ずSQLをメンテナンスすることになります。O/Rマッピングは、「効率を上げる」または「手間を軽減する」ものであって、SQLの理解が不要になるわけではありません。
上述のようにO/Rマッピングにおける煩雑な処理はすべてO/Rマッピングフレームワークが引き受けます。O/Rマッピングフレームワークを利用したデータベースの操作では、あたかもオブジェクトをそのまま扱っているかのように処理することができます。
一般的なO/Rマッピングフレームワークでは、次のような流れでマッピング処理が実現されます。
ここで、マッピングファイルを別途記述する作業によってプログラマの負担が増えてしまうように感じてO/Rマッピングの利用をちゅうちょするかもしれませんが、その心配には及びません。O/Rマッピングフレームワークの多くは、マッピング定義を記述したファイルから「データベーススキーマ」や「クラスのソースコード」を自動生成する仕組みを持っています。
またアプリケーションの外部にマッピングの定義を切り出すことは、データベースとアプリケーションの結合度を弱める働きがあります。つまりデータベーススキーマ変更の影響をマッピング時に吸収する効果や、アプリケーションの要求の変化をデータベースに及ぼさないようにする効果が望めます。
このようなO/Rマッピングの強力な仕組みを採用することによって、マッピングファイルの記述が負担になるどころか「テーブル定義の一元管理」や「テーブルとソースコードの同期管理」が容易となることが分かるでしょう。これらの作業が自動化できるのは、プログラムの管理者にとってマッピング処理以上の恩恵となるかもしれません。
最後に、O/Rマッピングフレームワークを利用するメリットを整理しましょう。
ここまでのまとめ:「O/Rマッピングフレームワークを利用するメリットは?」
次回は、JavaでO/Rマッピングを行う際の具体的な仕組みを解説します。さらに、Entity Beanとの比較、Javaにおける標準的なデータアクセス仕様としてサン・マイクロシステムズが提供しているJDOにも触れ、O/Rマッピングへの理解を深めることにします。
山本 大(やまもと だい)
株式会社クロノスに勤務するITアーキテクト。甲南大学 経営学部 卒業。J2EE、.NETにこだわらずベストソリューションを提供できるマルチプラットフォームアーキテクトを目指す。『XMLマスター教科書 プロフェッショナル』(翔泳社)や雑誌などで執筆活動も行っている。
Copyright © ITmedia, Inc. All Rights Reserved.