川久保 智晴 [著] 2010/05/14 14:00

サンプルコード 14.58 KB

 Java Persistence API(JPA)を使ってオブジェクトの世界とリレーショナルの世界を結び付ける方法を一緒に学んでいきたいと考えています。前編では1つのテーブルに対してCRUD操作を行いました。後編となる今回は、複数のテーブル間の関連をEntityモデルで表現する方法と、それらを扱うためのJPQLについて説明します。

1 2 3 4 5 6 →

はじめに

 JPA(Java Persistence API)とは、オブジェクトの世界からリレーショナルの世界へ、あるいはその逆への変換を行うためのAPIです。

 前編では、JPAを使用した1テーブルに対するCRUD操作を行うための実装方法を説明しました。後編となる今回は、複数のテーブルに対するCRUD操作について解説していきます。

ディレクションとカーディナリティのトラウマ

 オブジェクトモデルの世界でEntity間の関連は、ディレクションとカーディナリティという2つの軸を組み合わせます。Entity間の関連の扱い方は非常に難しいと思われがちです。特にEJB2.1以前のCMPを使った設計やコーディングの経験のある方は、設定ファイルにしろコーディングにしろ、学習も困難・実装も困難ということでトラウマとなったと思います。

 筆者自身もEJB2.1で多くのCMPを記述し、その困難さを身をもって知った技術者の1人です。そこで、Javaの世界はEJBからPOJOの世界へと一気に流れが変わったように思えます。しかし、EJBにはそれなりの魅力があることも確かです。ライフサイクルの管理をはじめ、多くの面倒な処理をEJBコンテナが行ってくれるからです。

Session Bean+JPA

 上記のトラウマこそ、筆者がEJBを捨てPOJOに逃げ込んだ原因です。とは言いつつも、JPA自体はPOJOをベースに作られているということからすれば、EJBの世界にJPAというPOJOベースのO/Rマッピングの技術が持ち込まれたことになり、Session BeanとJPAの組み合わせはEJBとPOJOのいいとこ取りをしていることになります。前編ではJavaアプリケーションを使いJPAを説明しましたが、今回は、EJBを使用した場合、いかに便利になるかを実感していただければと思います。

ディレクションとカーディナリティ

ディレクション

 オブジェクトモデルのディレクションは参照のフィールドの保持により決定します。AクラスとBクラスが存在し、AクラスがBクラスの参照のフィールドは持つが、BクラスはAクラスの参照のフィールドを持たない場合、単方向となります。クラス図ではAからBへの矢印で表します。AクラスとBクラスが互いの参照のフィールドを持つ場合、双方向となります。クラス図ではAとBの間に両方向の矢印で表します。

カーディナリティ

 オブジェクトモデルのカーディナリティは、参照のフィールドがコレクションか否かで決定します。AクラスとBクラスが存在し、それぞれ次のように呼ばれます。

  • 1対1(One-to-one):AクラスがBクラスのコレクションではない参照のフィールドを持ち、BクラスはAクラスへの参照を持たない場合、またはその逆の場合、さらにはお互いコレクションではない参照のフィールドを持つ場合のAクラスとBクラス
  • 1対多(One-to-many):AクラスがBクラスの参照のフィールドをコレクションとして持つ場合(BクラスはAクラスのコレクションではない参照を持っても構わない)のAクラスとBクラス
  • 多対1(Many-to-one):BクラスがAクラスの参照のフィールドをコレクションとして持つ場合(AクラスはBクラスのコレクションではない参照を持っても構わない)のAクラスとBクラス
  • 多対多(Many-to-many):AクラスがBクラスの参照のフィールドをコレクションとして持ち、BクラスもAクラスの参照のフィールドのコレクションを持つ場合のAクラスとBクラス

関連はディレクションとカーディナリティの組み合わせ

 関連のパターンはディレクションで2つ(単方向、双方向)、カーディナリティで4つ(One-to-one、One-to-many、Many-to-one、Many-to-many)があり、その組み合わせは単純に計算すると8つとなります。

 関連のパターンをクラス図で示すと次のようになります。ディレクションとカーディナリティはAクラスを基準としています。Many-to-manyの場合、単方向はないので、実質的には7つのパターンが存在します。これらのパターンを整理したのは@OneToOne、@OneToMany、@ManyToOne、@ManyToManyなどのアノテーションをEntityクラスのカラムに付与する必要があるためです。以下ではコレクションとしてListを使用していますが、SetやMapも使用可能です。

One-to-one
単方向
単方向
双方向
双方向
One-to-many
単方向
単方向
双方向
双方向
Many-to-one
単方向
単方向
双方向
双方向
Many-to-many
  • 単方向:該当無し
双方向
双方向

主と従

 双方向の場合、という関係があります。これはオブジェクトモデルではなく、リレーショナルモデルを元に決定します。双方向でMany-to-manyの場合は、どちらも主であり従となることができます。それ以外の双方向は、RDBの外部キーを持っているテーブルを表現しているEntityオブジェクト側が主となり、外部キーを持っていないテーブルを表現しているEntityオブジェクト側が従となります。

Entityクラスのアノテーション

 関連を持つフィールドの場合、ディレクションとカーディナリティの7つのパターン、および主と従という関係が理解できていれば適切にアノテーションを付与することが可能となります。カーディナリティはアノテーションを付与するのみで設定ファイルの変更が必要ないため、非常に分かりやすい記述が可能です。単方向でかつ相手の参照を持たない場合は、Columnアノテーションのみで済みます。


1 2 3 4 5 6
→
INDEX
今からでも遅くない JPAを学ぼう!(後編) オブジェクト間の関連を理解し、JPQLを使用する
Page1
はじめに
ディレクションとカーディナリティのトラウマ
ディレクションとカーディナリティ
Entity間の関連を実装する
知っていることと知っていないことの差は大きい
おさらい
プロフィール
川久保 智晴 カワクボ トモハル

COBOLで13年、Javaを中心としたWeb開発で11年。2つしか言語知らないのかというとそうでもなく、sed/awk、Perl、Pythonなども一時期は業務で使えるレベルまで達したと思っています(自己申告)。

最近はプロジェクトマネージャやソフトウェアアーキテクトという一見相容れない仕事を繰り返してきましたが、実は両者の技術は密接に絡んでいるというのが最近考えていることです。プロジェクトマネージャがあまりにも技術に疎かったり、ソフトウェアアーキテクトがあまりにもコストに鈍感であったりするのを見るにつけ思いが深まっています。

そういう会社員生活も2010年10月でピリオドを打ち、長年構想中のビジネスモデルをシステム化するために独立。2年後のビジネス化を目指しています。それまでの2年間はJavaを含めたプログラミング教室(http://www.programclass.com)で食いつなぐつもりです。2010年末時点で20名のJava教室の生徒さんがいます。Skypeを使っているので全国から問い合わせがあります。まだまだ募集していますので、気軽にメールを頂ければと思います。

以前はお酒が大好きでいろんなところに出没していましたが、今はおとなしく家飲みに徹しています。土日は20キロ近くジョギングしたりして爽やかなIT起業家となり雇用の創出に貢献できればと思っています。


記事へのコメント・トラックバック機能は2011年6月に廃止させていただきました。記事に対する反響はTwitterやFacebook、ソーシャルブックマークサービスのコメントなどでぜひお寄せください。

スポンサーサイト