連載
» 2013年07月02日 18時00分 公開

Play 2.xからMySQLに接続してAnormでCRUD操作するにはScala+Play 2.0でWebアプリ開発入門(7)(2/3 ページ)

[中村修太,クラスメソッド株式会社]

EvolutionsでDBの管理

 チームで開発を行っているとき、DBスキーマの変更で苦労したことがあるのではないでしょうか。

 DBを変更したけど、それを知らない他のメンバーの環境と不整合が生じてしまったりすることもあるので、各メンバ(または複数のマシン)でDBスキーマを統一することは重要です。

 PlayはRDBMSのスキーマ遍歴を追跡する方法を持っており、上記のようなケースで有用です。この章ではEvolutionsを使用してDBスキーマを更新してみましょう。

Evolutionスクリプトとは

 Evolutionsは、「Evolutionスクリプト」を使用することで、DBの変更を追跡します。このスクリプトは一定のルールに従ってSQLを記述するファイルです。デフォルトのDBに対してEvolutionスクリプトを実行したい場合、conf/evolutions/defaultディレクトリにスクリプトを保存します。

 スクリプトファイルに付ける名前は決められており、最初のスクリプトは1.sql、2番目のスクリプトは2.sqlというふうに、数値を順番に付けていかなければなりません。

 スクリプトファイルの内容は、次のようになっています。

# --- !Ups
create table foo (
  id int(10) not null auto_increment, 
  name varchar(100),
primary key(id));
alter table bar add newColumn varchar(10);
 
# --- !Downs
drop table foo;
alter table bar drop newColumn;

 Evolutionスクリプトは2つの部分で構成されています。「# --- !Ups」と書いてある部分からは、スキーマの変更内容を記述します。「# --- !Downs」と書いてある部分からは、Ups部分の変更を元に戻すための記述します。

 UpsもDownsも、上記のようにコメントで区切らなければいけません。

 また、次の条件を満たす場合、Evolution設定が自動で有効化されます。

  • DB設定が「conf/application.conf」で行われている
  • Evolutionスクリプトが所定のディレクトリに存在する

 もしEvolutionを無効化したい場合、conf/application.confで、下記設定を追加してください。

evolutionplugin=disabled

 開発モードでは、Evolutionが有効化されているとき、スキーマの状態はリクエストごとにチェックされます。その際にスキーマが最新状態でないと判断された場合、SQLを実行してスキーマを更新させるように促すページがブラウザに表示されます。

※本番モードの場合、アプリケーション起動前にスキーマがチェックされます

Evolutionsでデータベースを作成

 では、Evolutionsを使用して、スキーマの更新をしてみましょう。まずはユーザー情報を管理するテーブルを作成します。conf/evolutions/defaultディレクトリに、「1.sql」という名前で次のようなファイルを置きましょう。

# --- !Ups
create table User (
  id int(10) not null auto_increment, 
  name varchar(100),
  email varchar(100),
  password varchar(100), 
  createDate timestamp default current_timestamp(),
primary key(id));
# --- !Downs
drop table User;

 Playコンソールでアプリを起動し、「http://localhost:9000」にアクセスしてみましょう。次のような、Evolutionスクリプトを実行するように促すページが表示されます。

Evolutionスクリプト画面

 「Apply this script now!」と記述されたボタンを押すと、1.sqlの内容が実行されてスキーマが最新状態になります。mysqlのコンソールで確認してみると、Userテーブルが作成されているのが分かります。

 なお、「play_evolutions」という名前のテーブルも作成されています。これはEvolutionsがスキーマを管理するために使用するテーブルです。

 続けて、ユーザーがポストしたデータを管理するテーブルを作成します。2.sqlを次の内容で作成し、conf/evolutions/defaultディレクトリに置きましょう。

# --- !Ups
create table Post (
  id int(10) not null auto_increment,
  userId int(10) not null,
  title varchar(100) not null,
  body text,
  createDate timestamp default current_timestamp(),
  primary key(id),
  foreign key(userId) references USer(id)
);
# --- !Downs
drop table Post;

 「http://localhost:9000」にアクセスすると、先ほどと同じくEvolutionスクリプトの実行を促すページが表示されるので、スクリプトを実行しましょう。UserテーブルとPostテーブルができたら、準備は完了です。

 この章でやってきたように、Evolutions機能を使用することで、スキーマの状態を手軽に同期させることができます。Evolutionsについての詳細は、公式サイトの「Documentation: Evolutions ― Playframework」でも確認可能です。

Play ScalaでのDBアクセス

 Play2では、DBにアクセスするための方法は特に決まっていません。バンドルされている「Anorm」というライブラリを使用したり、「Slick」などのサードパーティ製ライブラリを使用することもできます(Play2-Javaでは、「EBean」というORMの使用が可能です)。

 本章では、Anormを使用して、Play2でのDBアクセスを行ってみましょう。

Play Scalaにおけるデータソースやコネクションを取得

 まずは、PlayでDBアクセスを使用する方法について解説します。DBアクセスをするには、play.api.dbパッケージのDBクラスを使用してデータソースやコネクションを取得します。

import play.api.db._
・
・
・
//データソース取得
val ds = DB.getDataSource()
//コネクション取得
val con = DB.getConnection()

 上記手法でデータソースやコネクションを取得できますが、使い終わった後は自分でclose()関数を呼び出す必要があります。なので、下記のような記述を用いてDBにアクセスするのが推奨されています。

//defaultデータベースにアクセス
DB.withConnection { implicit conn =>
  // DBアクセス処理
}

 ブロック内の処理を抜けると、ConnectionとともにStatement、ResultSetもcloseされます。また、default以外のDBを指定したい場合、withConnectionの第1引数で指定します。

 さらに、withTransaction関数を使用することで、ブロックの処理を1つのトランザクションとさせることができます。

DB.withTransaction { implicit conn =>
  // このブロックの処理は1つのトランザクションとなります
}

 さて、コネクションの扱い方は分かったので、Anormについて解説をしましょう。

Anormとは

 Anormを使用すると、SQLをそのまま使用してDBにアクセスできます。さらに、結果データをパースするための機能も持っています。この説明から分かるように、AnormはORMではありません。DBにアクセスするためにDSLは一切必要なく、SQLをそのまま使用します。

 また、AnormはJDBCデータをScalaのデータ構造へ変換するためのAPIを提供してくれます。

 Anormは既存のDBライブラリと比較すると、ちょっと取っ付きにくい部分があるかもしれませんが、AnormのAPIをScalaから使用することで、SQLの実行や取得したデータセットのパース処理をシンプルかつ柔軟に記述可能です。

 次ページでは、基本的なAnormの使用方法を見てみましょう。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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