はじめに
MVCのごく基本的なことが分かったら、次に見たいのは、本格的な開発で必要となる機能がどのような形で実装されているか、ということでしょう。今回は「1対多」「多対1」による複数モデルの連携処理についてと、JUnitを使ったアプリケーションのテストについてです。どちらも、実際に開発に利用する際には必要となる機能と言えます。これらがPlay!ではどのような形で作られているのかを考えていきましょう。
対象読者
- Javaで手ごろなフレームワークを探している技術者
- 最近のフレームワークをごくざっと理解しておきたい方
- Web開発の手法がどうも気に入らない、と常々考えているJavaプログラマ
モデルの連携を考える
前回、モデルの基本について説明をしましたが、単純に1つのモデルを作って動かすだけなら、非常に簡単に使用できることが分かりました。では、複数のモデルと連携する場合はどうなるのでしょうか。実際に作りながら考え方を見ていきましょう。
前回の簡単なメッセージ表示モデル(MsgData)に加え、ユーザー情報のモデルとしてPersonDataというクラスを作成することにしましょう。そしてMsgDataでは、nameではなく、このPersonDataのデータと関連付けることにします。こうした場合、SQLでは関連するデータのidなどを登録するフィールドを用意しておき、JOIN
を使って関連するテーブルまで含めて検索を行いました。しかし、Play!ではJPAを使い、データをSQLのテーブルではなく、オブジェクトとして永続化し管理しています。従って、モデルの連携も、オブジェクトとオブジェクトの関係をつける形で設計します。
まず、新しいPersonDataクラスを作成しましょう。「models」フォルダ内に、新たに「PersonData.java」というファイルを作成し、次のようにソースコードを記述します。
package models; import java.util.*; import javax.persistence.Entity; import javax.persistence.OneToMany; import play.db.jpa.Model; @Entity public class PersonData extends Model { public String name; public String mail; @OneToMany public List<MsgData> messages; public PersonData(String name,String mail){ this.name = name; this.mail = mail; this.messages = new ArrayList<MsgData>(); } }
ここでは、nameとmailという2つのフィールドのほかに、MsgDataインスタンスを保管するListをフィールドとして用意しています。ここに、関連するMsgDataをまとめようというわけです。このとき、注意しなければいけないのは「@OneToMany
アノテーションを用意する」ということでしょう。JPAでは、オブジェクトの永続化をするとき、こうした他のモデルのインスタンスの参照を含んでいると、そのままでは永続化できません。@OneToMany
をつけることで、このフィールドが一対多対応のオブジェクト参照のためのものであることをJPAに知らせることができます。
MsgDataの修正
続いて、MsgDataです。こちらも、nameの代りにPersonDataの参照を保管するように修正しておきましょう。
package models; import java.util.Calendar; import java.util.Date; import javax.persistence.Entity; import javax.persistence.ManyToOne; import play.db.jpa.Model; @Entity public class MsgData extends Model { private static final long serialVersionUID = 1L; public String message; @ManyToOne public PersonData person; public Date time = Calendar.getInstance().getTime(); public MsgData(String message,PersonData person){ this.person = person; this.message = message; person.messages.add(this); } }
こちらは、PersonDataインスタンスを保管するpersonフィールドを用意しています。そしてこれには「@ManyToOne
」というアノテーションをつけます。こうすることで、このMsgDataも永続化できるようになります。new
する際には、引数にPersonDataインスタンスを渡し、personプロパティに設定すると同時に、personのmessages.add
を呼び出してperson側にthisを保管するようにしています。