SQLに似たHQLでリレーショナルデータを柔軟に検索:Hibernateで理解するO/Rマッピング(5)(1/2 ページ)
O/Rマッピングは、従来の煩雑なデータベースに関する処理の記述をスマートにし、柔軟なアプリケーションの構築を可能にします。本連載ではオープンソースのO/Rマッピングフレームワーク「Hibernate」を用いてO/Rマッピングの基礎を解説します。そしてさらに、J2EEアプリケーションへの実践的な適用方法とそのメリットも紹介していきます。(編集局)
リレーショナルデータベースの特徴は、その名のとおりデータを「リレーショナル」に扱えることにあります。リレーショナルに扱えるデータとはID番号や名前などのキーとなるフィールドのデータを利用して、「結合」や「抽出」を行えるデータです。
O/Rマッピングフレームワークの良しあしを判断するうえで重要な点は、リレーショナルデータベースの強力な機能を殺さず、かつ扱いやすいAPI(アプリケーション・プログラミング・インターフェイス)を提供しているか否かという点です。今回はHibernateを使ったリレーショナルデータの表現方法を紹介します。
リレーショナルデータの準備と実行
今回のサンプルでは、テーブルを以下のように作成します。WorkGroupの1レコードに複数のMemberレコードが所属するという「1対多」のリレーションを持つテーブル構成となっています。使用するテーブルのER図は以下のようになります。
また、テーブルは以下のように作成します。
列名 | データ型 | 主キー | Not Null |
---|---|---|---|
NO | INTEGER | ○ | ○ |
NAME | VARCHAR(10) | ||
GROUPNO | INTEGER | ||
表1 Memberテーブルの定義 |
列名 | データ型 | 主キー | Not Null |
---|---|---|---|
GROUPNO | INTEGER | ○ | ○ |
GROUPNAME | VARCHAR(10) | ||
表2 WorkGroupテーブルの定義 |
作成したテーブルには、サンプルとして以下のようなテストデータを登録しておきます。
NO | NAME | GROUPNO |
---|---|---|
1 | iwashita | 1 |
2 | kawazu | 1 |
3 | kawano | 2 |
4 | Uozaki | 1 |
5 | masuda | 1 |
6 | mitsuyoshi | 2 |
7 | taga | 1 |
8 | tanaka | 2 |
9 | tanizawa | 1 |
10 | yamamoto | 2 |
11 | ysohida | 1 |
表3 Memberテーブルのサンプルデータ |
GROUPNO | GROUPNAME |
---|---|
1 | tokyo |
2 | osaka |
表4 WorkGroupテーブルのサンプルデータ |
マッピングファイルへの記述
テーブルが用意できたらマッピングファイルおよび永続化のためのJavaコードを作成していきましょう。まずは、Memberテーブルに対応するマッピングファイルを記述しましょう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
ここで、リスト1の中のコメント部分に関して少し詳細に解説しておきます。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
マッピングテーブルには主キーが必要です。Hibernateには永続化時に主キーの「値」を生成するためのIDジェネレータークラスが用意されています。サンプルでは「assigned」を使用しています。このIDジェネレーターは主キーの自動生成を行いません。よって、アプリケーション側で一意なIDを設定する必要があります。IDジェネレーターの一部を以下に紹介します。
名前 | 説明 |
---|---|
Increment | インクリメンタルなLong、Short、INT型のIDを生成します |
hilo | hi/loアルゴリズムを使用してIDを生成します |
uuid.hex | 128ビットのUUIDアルゴリズムを使用して文字列型のIDを生成しますuuid.string |
uuid.string | uuid.hexと同じアルゴリズムを使い、16けたのASCII文字でエンコードされたUUIDを生成します |
native | 使用するデータベースの機能に応じて、identity、sequence、またはhiloを選びます |
assigned | アプリケーションでIDを生成し、永続化される前にオブジェクトに割り当てる必要があります |
foreign | 1対1のリレーションが設定されているときに、関連先のオブジェクトのIDを使用します |
表5 IDジェネレーター |
このほかにも多くのIDジェネレーターが提供されています。詳しい使用方法などはHibernateのマニュアルを参照してください。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
MemberテーブルからWorkGroupテーブルへのマッピングを表現するタグとして<many-to-one>タグを使用します。
データベース設計に堪能な方なら「1対多」のリレーションはよくご存じでしょうが、「多対1」という呼び方にはなじみがないかもしれません。オブジェクト指向での「1対多」のリレーションは、そのリレーションが発生する主体によって「1対多」と「多対1」の2つの側面でとらえることができます。
サンプルで使用しているリレーションを、Memberテーブルを主体としてリレーションを見てみると、Memberテーブルのデータ複数に対してWorkGroupテーブルのデータが1つ決まるため「多対1」ということになりmany-to-oneのリレーションが使用されます。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
続いて、WorkGroupテーブルに対応するマッピングファイルを記述します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
「1対多」マッピングカラム
WorkGroupテーブルからMemberテーブルへの「1対多」のリレーションでは、複数レコードを扱う必要があるためコレクション型の指定が必要です。このサンプルではjava.util.Setインターフェイス型を用いてマッピングします。サンプルで使用している<set>タグのほかにも<map> <list> <bag>などがあります。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
Entity Javaコードの記述
次にJavaコードの中で使用する永続化クラスを作成します。これらのクラスは、EntityBeanの重厚なオブジェクトに対して、シンプルな普通のオブジェクトという意味を強調してPOJO(Plain Old Java Object)と呼ばれています。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
サンプル実行Javaコードの記述
さて、準備が整ったのでサンプルを実行するJavaコードを記述していきましょう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
プログラムを実行すると、以下のような出力情報がコンソールに表示されます。
Sessionインターフェイスのfind()メソッドに対して、SQLに似た文字列のクエリを指定することで検索結果が得られます。このクエリをHQL(Hibernate Query Language)と呼びます。このHQLによってWorkGroupにひも付くMemberのリストが得られました。この取得結果をイメージで表すと以下のようになります。
Copyright © ITmedia, Inc. All Rights Reserved.