Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

今からでも遅くない JPAを学ぼう!(後編)
オブジェクト間の関連を理解し、JPQLを使用する

ディレクション、カーディナリティは難しくない

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2010/05/14 14:00

ダウンロード サンプルコード (14.2 KB)

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

目次

はじめに

 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アノテーションのみで済みます。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 川久保 智晴(カワクボ トモハル)

    haruプログラミング教室(https://haru-idea.jp/)主宰。 COBOL、FORTRANで13年、Javaを中心としたWeb開発で11年。3つしか言語知らないのかというとそうでもなく、sed/awk、Perl、Python, PHP,  C#, JavaScript...

バックナンバー

連載:今からでも遅くない、JPAを学ぼう!
All contents copyright © 2005-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.5