連載
» 2012年06月06日 00時00分 公開

Javaの常識を変えるPlay framework入門(2):Play frameworkのDB操作を楽にするEBeanの基礎知識 (2/3)

[長谷川智之,株式会社ビーブレイクシステムズ]

Play frameworkの基本的なDB操作

 「play.db.ebean.Model」には、基本的なDB操作としてINSERT、UPDATE、DELETEが用意されています。

INSERT

 単純なINSERTなら、そのEBeanオブジェクトのsave()メソッドを呼べば、その状態で保存されます。

UPDATE

 UPDATEも、そのEBeanオブジェクトのupdate()メソッドを呼べば、変更した内容で更新されます。

DELETE

 UPDATE同様に対象のオブジェクトのdelete()メソッドを呼べば、そのオブジェクトは削除されます。

SELECT

 Play frameworkでは、検索を行う「play.db.ebean.Model.Finder」クラスが用意されています。このクラスを使うには、以下のようにFinderオブジェクトを作成します。

Finder<Long, Parent> finder = new Finder<Long, Parent>(Long.class, Parent.class);

 ここでのLongクラスはPrimary Keyのクラスを表し、Parentクラスは結果として返すクラスを意味します。下記は、このFinderクラスで今回使うメソッドです。

  • all():全件検索を行う
  • byId(Long id):Primary Keyによる検索を行う。引数のクラスはPrimary Keyとして指定したクラス
  • where(String arg):検索条件を指定し、Queryオブジェクトを取得。取得したQueryオブジェクトより、結果を取得

 そのほか、いろいろなメソッドが用意されています。さらに詳しく知りたい場合はPlay frameworkのAPIなどをご確認ください。

Playの再起動は不要! 手軽にDB操作を確認

 DB操作がどのような動きになるのか試しに実装してみましょう。まず、プロジェクトを作成したディレクトリのappフォルダにある「controllers/Application.java」を開いてください。

 そこでindex()メソッドを下記のように書き換えてください。

package controllers;
 
import java.util.List;
 
import models.Parent;
import play.db.ebean.Model.Finder;
import play.mvc.Controller;
import play.mvc.Result;
 
public class Application extends Controller {
 
    public static Result index() {
        // 1番目を保存
        Parent parent1 = new Parent();
        parent1.name = "新宿太郎";
        parent1.save();
 
        // 2番目を保存
        Parent parent2 = new Parent();
        parent2.name = "代々木太郎";
        parent2.save();
 
        // 3番目を保存
        Parent parent3 = new Parent();
        parent3.name = "原宿太郎";
        parent3.save();
 
        // 現在のParentを全検索して表示
        Finder<Long, Parent> finder = new Finder<Long, Parent>(Long.class,
                Parent.class);
        List<Parent> parents = finder.all();
 
        StringBuilder msg = new StringBuilder();
        for (Parent parent : parents) {
            msg.append(parent.toString()).append("\n");
        }
        return ok(msg.toString());
    }
}

 実行してみましょう。先ほどの「http://localhost:9000」に再度アクセスしてください。そうすると、実装されているDB操作が行われます。処理が終わると下記のように表示されていると思います。

Parent [id=1, name=新宿太郎, createDate=Sun Apr 08 22:56:25 JST 2012, updateDate=Sun Apr 08 22:56:25 JST 2012]
Parent [id=2, name=代々木太郎, createDate=Sun Apr 08 22:56:25 JST 2012, updateDate=Sun Apr 08 22:56:25 JST 2012]
Parent [id=3, name=原宿太郎, createDate=Sun Apr 08 22:56:25 JST 2012, updateDate=Sun Apr 08 22:56:25 JST 2012]

 作成したParentが保存されているのが確認できましたね。

※ ここではINSERT処理のみを行っているので、このページにアクセスするたびに、同様のレコードを繰り返し作成されるので注意してください。

 次に、parent1のnameを変更し、parent2を削除してみましょう。先ほどのApplication.javaを下記のように修正してください。

package controllers;
 
import java.util.List;
 
import models.Parent;
import play.db.ebean.Model.Finder;
import play.mvc.Controller;
import play.mvc.Result;
 
import com.avaje.ebean.Query;
 
public class Application extends Controller {
 
    public static Result index() {
 
        // 検索クラス
        Finder<Long, Parent> finder = new Finder<Long, Parent>(Long.class,
                Parent.class);
        
        // parent1 の取得(条件を指定した検索)
        Query<Parent> query = finder.where("name='新宿太郎'");
        Parent parent1 =query.findUnique();
 
        // parent2 の取得(Idからの検索。Idは保存したときに振られたId)
        Parent parent2 =finder.byId(new Long(2));
        
        // 1番目の名前を更新します
        parent1.name = "新宿次郎";
        parent1.update();
 
        // 2番目を削除します
        parent2.delete();
 
        // 現在のParentを全検索して表示
……【略】……
    }
}

 実装後に先ほどの「http://localhost:9000」に再度アクセスしてください。更新されたレコードのnameとupdateDateが更新され、削除されたレコードは表示されないはずです。

※Playの再起動などは不要です。Webブラウザで再度アクセスするだけで十分です。

Parent [id=1, name=新宿次郎, createDate=Sun Apr 08 22:56:25 JST 2012, updateDate=Sun Apr 08 23:24:09 JST 2012]
Parent [id=3, name=原宿太郎, createDate=Sun Apr 08 22:56:25 JST 2012, updateDate=Sun Apr 08 22:56:25 JST 2012]

親子関係にあるDBデータの操作

 ここまでは、1つのDBテーブルに対してのアクセス方法を説明してきました。しかし、私たちが作成するシステムでは複数のDBテーブルが関係し、親子関係になっていることがほとんどです。次に、親子関係にあるデータについて操作してみましょう。

 今回は1つの親が複数の子を持つだけのシンプルな関連を持つクラスを作成します。最初に下記のような子のクラスを作成してください。

package models;
 
import java.util.Date;
 
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Version;
 
import play.db.ebean.Model;
 
import com.avaje.ebean.annotation.CreatedTimestamp;
import com.avaje.ebean.validation.NotNull;
 
@Entity
public class Child extends Model {
 
    @Id
    public Long id;
 
    @ManyToOne
    @JoinColumn(name = "parent_id")
    public Parent parent;
 
    @NotNull
    public String name;
 
    @CreatedTimestamp
    public Date createDate;
 
    @Version
    public Date updateDate;
 
    public String toString() {
        return "Child [id=" + id + ", parent.id=" + parent.id + ", name="
                + name + ", createDate=" + createDate + ", updateDate="
                + updateDate + "]";
    }
}

 次にParentクラスに、Childクラスと関連を持つためのプロパティとして、以下のコードを記述してください。

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
    public List<Child> children = new ArrayList<Child>();

親子関係にあるDBデータの操作で使うアノテーション

 それでは、新しく出てきたアノテーションを簡単に説明します。

  • Childクラス
    • @ManyToOne:複数の子クラスが1つの親クラスに属することを示す
    • @JoinColumn(name="parent_id"):ChildテーブルがParentテーブルと関連を持つカラムはparent_idであることを示す
  • Parentクラス
    • @OneToMany(cascade = CascadeType.ALL, mappedBy="parent"):Parentクラスが複数のChildクラスを持ち、Childクラスのクラス変数parentで関連することを示し。この"parent"はChildで指定された変数名と一緒でないとエラーになる。また、すべてのオペレーションに対してカスケードされる

親子関係にあるDBデータの作成

 「http://localhost:9000」に再びアクセスしてください。以下のページが表示されます。

 ここにある「Apply this script now!」をクリックすると、ParentのDBテーブルはいったん削除された後に再作成され、ChildのDBテーブルが新たに作成されます。下記は、このとき実行されるSQLです。

SET REFERENTIAL_INTEGRITY FALSE;
 
drop table if exists parent;
 
SET REFERENTIAL_INTEGRITY TRUE;
 
drop sequence if exists parent_seq;
 
create table child (
  id                        bigint not null,
  parent_id                 bigint,
  name                      varchar(255) not null,
  create_date               timestamp not null,
  update_date               timestamp not null,
  constraint pk_child primary key (id))
;
 
create table parent (
  id                        bigint not null,
  name                      varchar(255) not null,
  create_date               timestamp not null,
  update_date               timestamp not null,
  constraint pk_parent primary key (id))
;
 
create sequence child_seq;
 
create sequence parent_seq;
 
alter table child add constraint fk_child_parent_1 foreign key (parent_id) references parent (id) on delete restrict on update restrict;
create index ix_child_parent_1 on child (parent_id);

 次ページでは、変更したEBeanを使って簡単な親子関係のDB操作を行ってみましょう。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。