【Play Framework 2.4】Ebeanを使った検索処理

f:id:mofmof721:20151227114038p:plain:w200
Play Framework 2.4技術メモ第二回。
今回はDB接続について。
公式のドキュメントはこちら
https://www.playframework.com/documentation/2.4.x/SettingsJDBC


目次

DB情報

DBはMySQLを使います。DBの設定は先に済ませておいてください。
今回は以下の設定でDBを作成しました。

データベース名:play_test
ユーザー名:play_test
パスワード:play_test

設定ファイルの編集

application.confの設定

(プロジェクトのディレクトリ)→conf→application.confを開きます。
30行目付近からDBの設定が書いてある箇所があるので、コメントアウトを外し、自分の環境に合わせて記述を書き換えます。

# Database configuration
# ~~~~~
# You can declare as many datasources as you want.
# By convention, the default datasource is named `default`
#
db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://localhost/play_test?characterEncoding=UTF8"
db.default.username=play_test
db.default.password="play_test"

イコール以下を自分の環境に合わせて設定します。

40行目付近にEvolutionsの設定があります。
Evolutionsはddlの作成・実行を自動で行う機能です。
最初の状態はplay.evolutions.enabled=falseコメントアウトされていて、Evolutionsを使用する設定になっています。

今回はコメントアウトを外してEvolutionsを使わないよう設定します。
Evoluthinsを使う場合はコメントアウトしたままでOKです。

# Evolutions
# ~~~~~
# You can disable evolutions if needed
play.evolutions.enabled=false

一番下の行に、以下の一文を追加します。

ebean.default = ["models.*"]

application.confの全文はこうなります。

# This is the main configuration file for the application.
# ~~~~~

# Secret key
# ~~~~~
# The secret key is used to secure cryptographics functions.
#
# This must be changed for production, but we recommend not changing it in this file.
#
# See http://www.playframework.com/documentation/latest/ApplicationSecret for more details.
play.crypto.secret = "changeme"

# The application languages
# ~~~~~
play.i18n.langs = [ "en" ]

# Router
# ~~~~~
# Define the Router object to use for this application.
# This router will be looked up first when the application is starting up,
# so make sure this is the entry point.
# Furthermore, it's assumed your route file is named properly.
# So for an application router like `my.application.Router`,
# you may need to define a router file `conf/my.application.routes`.
# Default to Routes in the root package (and conf/routes)
# play.http.router = my.application.Routes

# Database configuration
# ~~~~~
# You can declare as many datasources as you want.
# By convention, the default datasource is named `default`
#
db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://localhost/play_test?characterEncoding=UTF8"
db.default.username=play_test
db.default.password="play_test"

# Evolutions
# ~~~~~
# You can disable evolutions if needed
play.evolutions.enabled=false

# You can disable evolutions for a specific datasource if necessary
# play.evolutions.db.default.enabled=false

ebean.default = ["models.*"]

build.sbtの設定

(プロジェクトのディレクトリ)→build.sbtを開きます。
sbtはライブラリの管理などを行うビルドツールです。
build.sbtに設定を追加して、必要なライブラリをダウンロードするよう設定します。

5行目あたりにlazy val root = (project in file(".")).enablePlugins(PlayJava)の記述があるので、
enablePluginsのかっこの中に,PlayEbeanを追加します。

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

9行目付近からlibraryDependencies ++= Seq(…)の記述があるので、Seqのかっこ内に必要なライブラリを記述します。
今回はevolutionsとMySQL Connectorを追加します。

libraryDependencies ++= Seq(
  evolutions,
  javaJdbc,
  cache,
  javaWs,
  "mysql" % "mysql-connector-java" % "5.1.20"
)

build.sbt全文はこうなります。

name := """play-test"""

version := "1.0-SNAPSHOT"

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

scalaVersion := "2.11.6"

libraryDependencies ++= Seq(
  evolutions,
  javaJdbc,
  cache,
  javaWs,
  "mysql" % "mysql-connector-java" % "5.1.20"
)

// Play provides two styles of routers, one expects its actions to be injected, the
// other, legacy style, accesses its actions statically.
routesGenerator := InjectedRoutesGenerator

これで設定が完了したので、検索処理を実装します。

検索処理を実装する

Ebeanとは

今回はEbeanを使ってDB操作を行います。

Ebeanは、Javaのためのオブジェクト関係マッピング (ORM)ライブラリである。JPA (Java Persistence API) やJDO (Java Data Objects) よりもシンプルに使えて、かつ理解しやすいように設計されている。
Ebean - Wikipedia

Play Frameworkについて解説した記事ではEbeanを使っていることが多いので、こちらでもEbeanを使います。

作成したテーブル

今回は以下のSQLでユーザーマスタを作成しました。

CREATE TABLE `user_master` (
  `user_id` char(64) NOT NULL,
  `user_name` varchar(100) NOT NULL,
  `password` varchar(64) NOT NULL,
  `regist_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `update_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

このテーブルに合わせてエンティティクラスを実装します。

エンティティクラスの作成

(プロジェクトのディレクトリ)→app内にmodelsパッケージを作成します。
以後、このパッケージ内にエンティティクラスを作成します。
今回はUserMasterクラスを作成しました。
f:id:mofmof721:20151227205317p:plain

エンティティクラスではcom.avaje.ebean.Modelクラスを継承します。

package models;

import com.avaje.ebean.Model;

/**
 * ユーザーマスタエンティティクラス
 *
 */
public class UserMaster extends Model {

}

Play 2.3までではplay.db.ebean.Modelクラスを使用していましたが、
Play 2.4からplay.db.ebean.Modelクラスが非推奨になり、com.avaje.ebean.Modelクラスに変更されました。

エンティティクラスの中身を実装します。
各カラム用の変数をメンバ変数で作ります。

package models;

import java.sql.Timestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

import com.avaje.ebean.Model;
import com.avaje.ebean.annotation.CreatedTimestamp;
import com.avaje.ebean.annotation.UpdatedTimestamp;

/**
 * ユーザーマスタエンティティクラス
 *
 */
@Entity
@Table(name = "user_master")
public class UserMaster extends Model {

	/**
	 * ユーザーID
	 */
	@Id
	@Column(name = "user_id")
	private String userId;

	/**
	 * ユーザー名
	 */
	@Column(name = "user_name")
	private String userName;

	/**
	 * パスワード
	 */
	@Column(name = "password")
	private String password;

	/**
	 * 登録日時
	 */
	@CreatedTimestamp
	@Column(name = "regist_time")
	private Timestamp registTime;

	/**
	 * 更新日時
	 */
	@UpdatedTimestamp
	@Column(name = "update_time")
	private Timestamp updateTime;

	/**
	 * find
	 */
	private static Find<Long, UserMaster> find = new Find<Long, UserMaster>() {
	};

	/**
	 * ユーザーID取得
	 *
	 * @return ユーザーID
	 */
	public String getUserId() {
		return userId;
	}

	/**
	 * ユーザーID設定
	 *
	 * @param userId
	 *            ユーザーID
	 */
	public void setUserId(String userId) {
		this.userId = userId;
	}

	/**
	 * ユーザー名取得
	 *
	 * @return ユーザー名
	 */
	public String getUserName() {
		return userName;
	}

	/**
	 * ユーザー名設定
	 *
	 * @param userName
	 *            ユーザー名
	 */
	public void setUserName(String userName) {
		this.userName = userName;
	}

	/**
	 * パスワード取得
	 *
	 * @return パスワード
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * パスワード設定
	 *
	 * @param password
	 *            パスワード
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * 登録日時取得
	 *
	 * @return 登録日時
	 */
	public Timestamp getRegistTime() {
		return registTime;
	}

	/**
	 * 登録日時設定
	 *
	 * @param registTime
	 *            登録日時
	 */
	public void setRegistTime(Timestamp registTime) {
		this.registTime = registTime;
	}

	/**
	 * 更新日時取得
	 *
	 * @return 更新日時
	 */
	public Timestamp getUpdateTime() {
		return updateTime;
	}

	/**
	 * 更新日時設定
	 *
	 * @param updateTime
	 *            更新日時
	 */
	public void setUpdateTime(Timestamp updateTime) {
		this.updateTime = updateTime;
	}

	/**
	 * find取得
	 *
	 * @return find
	 */
	public static Find<Long, UserMaster> getFind() {
		return find;
	}

	/**
	 * find設定
	 *
	 * @param find
	 *            find
	 */
	public static void setFind(Find<Long, UserMaster> find) {
		UserMaster.find = find;
	}
}

各種アノテーションを使い、テーブル名やカラム名などを設定しています。

@Entity

エンティティクラスであることを示すアノテーション

@Table

name = ○○でテーブルの物理名を設定しています。

@Id

そのカラムが単独PKであることを示すアノテーション

@Column

name = ○○でカラムの物理名を設定しています。

@CreatedTimestamp

登録日時を示すアノテーション
このアノテーションを設定すると、登録処理を行ったときに自動で処理日時が設定されます。

@UpdatedTimestamp

更新日時を示すアノテーション
このアノテーションを設定すると、更新処理を行ったときに自動で更新日時が設定されます。

Find

FindクラスはSELECT文を生成するクラスです。
Play 2.3まででは検索処理にplay.db.ebean.Model.Finderクラスを使用していましたが、2.4ではplay.db.ebean.Modelクラスが非推奨になり、
代わりにPlay 2.4からcom.avaje.ebean.Model.Findクラスを使用するようになっています。

検索を実行する

(プロジェクトのディレクトリ)→controllersにApplicationクラスがあります。
今回はこの中に検索処理を実装します。

package controllers;

import play.mvc.Controller;
import play.mvc.Result;

import views.html.index;

public class Application extends Controller {

	public Result index() {
		// ここに検索処理を実装する

		return ok(index.render("Your new application is ready."));
	}

}

returnの前にユーザーマスタを全件検索し、取得したデータの利用者名をコンソールに出力する処理を書きました。

package controllers;

import java.util.List;

import models.UserMaster;
import play.mvc.Controller;
import play.mvc.Result;

import views.html.index;

/**
 * コントローラークラス
 *
 */
public class Application extends Controller {

	/**
	 * index画面アクセス時処理
	 *
	 * @return 処理結果
	 */
	public Result index() {
		// ユーザーマスタを検索する
		List<UserMaster> userMasterList = UserMaster.getFind().all();
		for (UserMaster data : userMasterList) {
			// 利用者名を出力する
			System.out.println(data.getUserName());
		}
		// index画面を表示する
		return ok(index.render("Your new application is ready."));
	}

}

全件検索を行う場合はcom.avaje.ebean.Model.Find.all()メソッドを使用します。

検索結果を確認する

テーブルには以下のデータを登録してあります。

user_id user_name password regist_time update_time
0000000001 田中 太郎 tanaka 2015/12/27 20:36:56 2015/12/27 20:36:56
0000000002 山田 一郎 yamada 2015/12/27 20:36:56 2015/12/27 20:36:56


サーバーを起動し、localhost:9000にアクセスします。
登録したユーザー名がコンソールに表示されているので、検索結果の出力が成功していることが確認できます。
f:id:mofmof721:20151227214105p:plain

参考

MySQLのDB接続設定はこちらの記事を参考にしました。
qiita.com

Ebeanの使い方はこちらを参考にしました。
mpon.hatenablog.com