読者です 読者をやめる 読者になる 読者になる

8t's BBR

よくつまったあれこれをメモ

Play Framework を使ってみた ③

web系

前記事:Play frameworkを使ってみた ② - 8t's BBR


前回からかなり時間が経ってしまいましたが、今回はPlayフレームワーク
データベースとEbeanを扱うにはどうするかについてまとめようかと思います。


※データベース初心者が送るデータベース初心者向けの説明になります。厳しい指摘は歓迎します。

※play2.5系のjavaの説明になるので、違うバージョンまたはscala使用者は公式などを参考にしてください。
Home - 2.5.x

データベースを扱うための設定

conf/application.conf

データベースの情報を記述します。単一のデータベースしか扱わないのであればデータソースの名前はdefaultのままで大丈夫です。
H2とかSQLiteとか色んなデータベースを扱うことができますが、今回はMySQLを例にとって説明していきます。

db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://localhost/playdb"
db.default.username=playdbuser
db.default.password="a strong password"

urlの最後は使用するデータベース名。usernameやpasswordは各自設定したものを。

build.sbt

以下の設定がなされていることを確認。なければ設定してください。

libraryDependencies += javaJdbc

また、使用するデータベースがH2以外のものであれば、以下の設定も必要です。
以下の例はMySQLの場合。最後の数字部分はバージョンですので適宜変更を。

libraryDependencies += "mysql" % "mysql-connector-java" % "5.1.36"

 

データベースへのアクセス

以下のようにするだけでデータベースを利用できます。

import javax.inject.Inject;
import play.mvc.*;
import play.db.*;

class Application extends Controller {

    private Database db;

    @Inject
    public Application(Database db) {
        this.db = db;
    }

}

クエリ実行

あまり推奨しませんが(理由は後述)、以下のようにすればクエリを実行できます。

import javax.inject.Inject;
import play.mvc.*;
import play.db.*;
import java.sql.*;

class Application extends Controller {

    private Database db;
    private Statement stmt;

    @Inject
    public Application(Database db) {
        this.db = db;
        Connection con = db.getConnection();
 
        try {
            stmt = con.createStatement();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public Result getMemberList() {
        String query = "SELECT * FROM MEMBER";
        ResultSet rs = stmt.executeQuery(query);
//             :          
        return ok();
    }

}

Ebeanの利用

先ほどクエリの実行の仕方を紹介しましたが推奨しませんと言いました。なぜなら、

  • クエリをコード中に書く必要がある
  • コードの記述量が多くなる

といったことによって、ミスをする可能性が高くなったり、読みづらくなったりと問題点があるからです。

では、どうすればいいのか。これをサポートする機能をPlayは提供してくれています。
具体的にはEbeanというものを利用することになります。
これ自体についてはまだ知ったばかりなので間違っているかもしれませんが、DB操作を楽にしてくれるものです。
たった一行でDB操作が可能になります。すごいですね。


では早速、設定ファイルをいじっていきます。

project/plugins.sbt

まずはこのファイルの最後に以下の設定を記述します。

addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "3.0.0")

build.sbt

次に、PlayEbeanのプラグインを有効化します。おそらく最後のPlayEbeanの部分を追記するだけで大丈夫です。
PlayEbeanを認識してくれない場合がありますが、build.sbtをリフレッシュすれば直ります。(これに気づけず、すごい時間を浪費しました・・・)

lazy val root = (project in file(".")).enablePlugins(PlayJava, PlayEbean)

conf/application.conf

データソースの名前がdefaultのままであれば、以下の記述を追記してください。
違う場合はそれに合わせてdefault部分を変更してください。

ebean.default = "models.*"

この設定ではmodelsパッケージ以下を管理する形になりますが、お好きなパッケージを指定しても大丈夫です。



以上で準備完了です。


実際の利用例

まずは、データベースで管理するデータをクラスとして作成します。
ポイントはクラス宣言の前に@Entityアノテーションを付与することです。
これにより、データベースが管理するエンティティクラスとなります。


以下は適当に作成したMemberクラスです。

package models;

import java.util.*;
import javax.persistence.*;

import com.avaje.ebean.Model;
import play.data.format.*;
import play.data.validation.*;

@Entity
public class Member extends Model {

    @Id
    public Long id;

    @Constraints.Required
    public String name;

    public boolean isMale;

    public Long score;

    public static Finder<Long, Member> find = new Finder<Long,Member>(Member.class);
}
  • @Id : 登録時、主キーとなるIDを自動生成してくれるようになる。
  • @Constarints : 値の制限をかけることができる。Requiredの他にも色々ある。
  • Finder : 検索時に使います。おまじない的に書いてしまいましょう。

 


あとはMemberクラスのインスタンス(member)を生成すれば、

member.save();

で、データベースに登録できます。memberインスタンスのidは自動で生成されます。
idの値を保持しており、他の情報を変更したい場合は、

member.update();

とするだけです。


逆にデータベースからデータを引き出し、それを元にインスタンス生成することもできます。

Member member = Member.find.byId(id);

データを削除したい場合は、この後に

member.delete()

とするだけです。なんとわかりやすいことか。

トランザクション

データベースを扱うのであれば当然必要です。
メソッドに@Transactionalをつけるか、Ebean.beginTransaction()Ebean.commitTransaction()Ebean.endTransaction()を活用するかのどちらかで対応できます。