Tech Sketch Bucket of Technical Chips by TIS Inc.

Scala/Play2でWebアプリケーション開発~(4)SlickコードジェネレータとTypesafe Activatorの利用

Pocket

前回の Scala/Play2でWebアプリケーション開発~(3)入力チェックの実装(Javaライブラリの活用とBootstrap3への対応) までの記事でPlay2とSlickを使って、登録・参照・更新・削除を行う簡単なWebアプリケーションを作成し、画面入力項目に対してチェック処理を追加しました。これまでの過程では利用していませんでしたが、データベースアクセスライブラリである「Slick」にはバージョン2.0.0からソースコードのジェネレート機能が追加されました。今回は「Slick Code Generator」とScalaのプロジェクトを簡単に作成できる「Typesafe Activator」について紹介します。

Slick Code Generatorとは?

Slickのコードジェネレータは、データベースへアクセスするためのソースコードをデータベーススキーマから生成する機能です。前回作成した簡単アプリケーションは、ソースコードからデータベーススキーマを作成していました。しかし、実際のアプリケーションの開発過程は、データベース設計を先に行うケースも多々あるかと思います。そういう場合はスキーマからソースコードを生成する今回のアプローチが有効になります。ObjectBrowserERのようなツールを活用しER図からデータベーススキーマを生成し、データベーススキーマからソースコードを生成することで、ER図からソースコードがシームレスにつながります。開発途上、あるいは保守フェーズでデータベースモデルが進化するケースでは非常に有効です。

<前回までのアプローチ>
codetoschema.png

<今回のアプローチ>
schematocode.png

「Slick Code Generator」の最新情報は、 Slickの本家サイトのドキュメント(Slick2.0.1 documentation)の「SCHEMA CODE GENERATION を御覧ください。

今回は、ER図から生成したデータベーススキーマが準備出来ていることを前提に、ソースコードをジェネレートしてみます。
データベーススキーマは前回EVENTテーブルを作成したスキーマを利用します。必須項目であるEVENTテーブルの「イベントID」と「イベント名」には「NOT NULL」制約を付与しておきます。

「NOT NULL」制約を付与するSQL

前回までのソースコード

本記事で紹介するソースコードはGitHub上で公開しています。
https://github.com/tech-sketch/scala-play2-sample

前回記事( Scala/Play2でWebアプリケーション開発~(3)入力チェックの実装(Javaライブラリの活用とBootstrap3への対応) )終了時点のソースコードは以下のタグからご覧いただけます。
https://github.com/tech-sketch/scala-play2-sample/tree/3.0

Scalaのソースコードをジェネレートする

ソースコードのジェネレートを行う前に、Slickのバージョンを最新の2.0.1にアップデートしておきましょう。ライブラリのバージョン変更は「Build.scala」を編集します。Slickのバージョンを「2.0.0」から「2.0.1」に変更します。

Build.scala (/project)

「Build.scala」を変更した後、PlayコンソールからEclipseのプロジェクトファイルを再生成する必要があります。詳細な手順は前回記事 「Scala/Play2でWebアプリケーション開発~(3)入力チェックの実装(Javaライブラリの活用とBootstrap3への対応)」 の「単項目チェック5: Javaライブラリを活用して独自のチェックを作る。」を参照してください。

SlickのコードジェネレータはSlickのライブラリ自体に含まれており、新たにライブラリを取り込んだり環境設定の必要がありません。データベーススキーマに接続するために必要な情報をパラメータとして「scala.slick.model.codegen.SourceCodeGenerator」オブジェクトの「main」関数を呼ぶだけです。

それでは、イベント登録画面に「Slick Generate」ボタンを追加してみましょう。データベースへの接続に必要な情報を、以下の通り設定します。ユーザ名とパスワードはSlickの2.0.1から指定できるようになりました。尚、バージョン2.0.1では接続先スキーマを指定するにはジェネレータのカスタマイズが必要です。

 項目 設定値
 Slickドライバー scala.slick.driver.H2Driver
 JDBCドライバー org.h2.Driver
 URL jdbc:h2:tcp://localhost:9092/demo 
 ソースコード出力先フォルダ  app/
 パッケージ名 models
 ユーザ名 sa
 パスワード [空文字]

EventCreateコントローラに「slickgen」関数を作成し、上記データベース情報をパラメータとして「scala.slick.model.codegen.SourceCodeGenerator」オブジェクトの「main」関数を呼び出します。

[Controller] EventCreate.scala (/app/controllers/event)

ジェネレート後は、イベント登録画面に「ソースコードをジェネレートしました。」というメッセージを表示します。
次に、イベント登録画面にジェネレートを実行するためのボタンを作成しておきます。

[View] eventCreate.scala.html (/app/views/event)

続いて、routesファイルにURLを定義します。

routes (/conf)

それでは、イベント登録画面に追加した「Slick Generate」ボタンからソースコードをジェネレートしてみましょう。

eventCreate1.png

出力先「app/」ディレクトリの下の「models」パッケージを確認してみましょう。「Tables.scala」というファイルが作成されているはずです。以下がSlickのコードジェネレータにより生成されたソースコードです。

[model] Tables.scala (/app/models)

Tablesトレイトに「Event」という名前のクラスと「EventRow」という名前のケースクラスが作成されています。各クラスにはテーブルのカラムに対応するプロパティが生成されています。それぞれのプロパティの型はテーブルのカラムの型を元に生成されています。「Integer型」の「ID」は「Int型」に、「VARCHAR型」の「イベントID」は「String型」に、「DATE型」の開催日は「SQLDATE型」にマッピングされます。
では、その他のH2のデータ型はどうでしょうか?主要なデータ型について確認したところ、以下のようにマッピングされることが分かりました。また、テーブルのカラムにNULL値が許容される(NOT NULL制約が付与されていない)場合は「Option型」になります。

 H2データ型 Table.scalaデータ型
 INT Int
 BOOLEAN Boolean
 TINYINT Byte
 SMALLINT Short
 BIGINT Long
 IDENTITY_COL Long
 DECIMAL scala.math.BigDecimal 
 DOUBLE Double
 REAL Float
 TIME java.sql.Time
 DATE java.sql.Date
 TIMESTAMP java.sql.Timestamp
 BINARY java.sql.Blob
 OTHER String
 VARCHAR String
 VARCHAR_IGNORECASE  String
 CHAR String
 BLOB java.sql.Blob
 CLOB java.sql.Clob
 UUID java.sql.Blob
 ARRAY String
 GEOMETRY String

 
さて、ジェネレートしたTables.scalaの「Event」と「EventRow」は、それぞれ、前回作成した「EventTag」と「Event」に該当します。

前回作成したクラスジェネレートしたクラス
 EventTag Event
 Event(case class)  EventRow

このように、ジェネレートしたソースコードは既に作成済みのコードと重複するロジックがありますので、重複箇所は前回のコードを削除し、ジェネレートしたコードを利用するように修正しておきます。

前回作成した「Event」オブジェクトは、ジェネレートしたクラスと名前が重複するので「Events(Events.scala)」とします。EventTagクラスは、TablesトレイトにEventクラスとして生成されているため削除します。変数「events」も同様にTablesオブジェクトに「Event」として定義されているため削除します。これに伴い、「events」を呼び出している箇所は全て「Event」に修正しましょう。
また、Caseクラスである「Event」は「EventRow」に変更されていますので、こちらも修正しておきましょう。修正済みの「Events.scala」は以下のようになります。

[Model]Events.scala (/app/models)

コントローラにも若干の修正が必要です。「models.Events」のインポートを削除し、「models.Tables._」をインポートします。Caseクラス「Event」を使用している箇所は「EventRow」を使用するよう修正します。「EventCreate.scala」と「EventUpdate.scala」を修正しておきましょう。

[Controller] EventCreate.scala (/app/controllers/event)

[Controller] EventUpdate.scala (/app/controllers/event)

ビューからもCaseクラス「Event」を参照していましたので「EventRow」に修正します。

[View] eventSearch.scala.html (/app/views/event)

以上で修正は完了になりますので、再度アプリケーションの動作を確認しておきましょう。
正しく動作しましたでしょうか?

このように、Slick Code Generatorを使うことで、多くのソースコードをデータベーススキーマから自動生成することが出来ます。ER図があれば、データベーススキーマを生成することは容易ですので、そのスキーマを活用し、ソースコードをジェネレートすれば開発を効率化することが出来ます。データベーススキーマはシステムとともに進化しますので、そういった場面で更に効果を発揮することでしょう。

「Typesafe Activator」を利用する

ここまでは、ScalaのコードからGeneratorを呼び出しソースコードをジェネレートする方法を紹介しました。他にも、Slickのコードジェネレータはsbtを利用して実行することも出来ますので、この方法も紹介しておきます。

ビルドスクリプトを記述することでジェネレートを実行できますが、Typesafeが提供する「Typesafe Activator」を使うとより簡単に実行することが出来ますので、そちらの方法を紹介します。

1. 「Typesafe Activator」とは

「Typesafe Activator」とは、Scalaをはじめ、「Play Framework」や「Akka」などTypesafeのプロダクトを利用する際に、簡単に使いはじめることが出来るようサポートしてくれるツールです。Webブラウザから操作するだけで目的に合ったブランクアプリを作成たり、作成したソースコードを参照する事ができます。それだけでなく、作成したソースコードを編集したり、コンパイル・テスト・インスペクション・アプリケーションの実行もすべてWebブラウザ上から行うことが出来ます。そして、Webブラウザ上から作成したアプリケーションをIDEにインポートし、本格的な開発をスタートします。

TypesafeActivatorImage.png

2. 「Typesafe Activator」のインストール

使いはじめる前には「Typesafe Activator」自体の環境設定が必要ですが非常に簡単です。

  • (1) ダウンロード
    以下のURLから「DOWNLOAD TYPESAFE ACTIVATOR」をクリックし、環境に応じた最新の「Typesafe Activator」をダウンロードします。
    http://typesafe.com/platform/getstarted
  • (2) 展開
    執筆時点の最新「typesafe-activator-1.1.2.zip」ファイルを任意のディレクトリ(C:\pleiades\activator-1.1.2)に展開します。
  • (3) プロキシ設定
    「<ユーザホームディレクトリ>/.activator」に「activatorconfig.txt」というファイルを作成し、プロキシの設定を記述します。

activatorconfig.txt (C:\Users\\.activator)

「Scala/Play2でWebアプリケーション開発~(1)環境構築&デフォルトアプリの解説」 で、環境変数に「HTTP_PROXY=http://<プロキシホスト名>:<プロキシポート番号>」を設定済みの場合は、本手順は不要です。

3. 起動

Windowsの場合は展開したディレクトリ(C:\pleiades\activator-1.1.2)配下の「activator.bat」をダブルクリックし、「Typesafe Activator」を起動します。クライアントPC上でWebシステムとして起動し、Webブラウザが自動的に起動され、「Typesafe Activator」にアクセスすることが出来ます。起動ログを確認すると「Play Framework」が利用されていることが分かります。

TypesafeActivator-top.png

4. プロジェクトの作成

  • (1) テンプレートの選択
    「Typesafe Activator」のトップ画面が表示されたら、まずは利用するテンプレートを選択します。今回は、「Using Slicks default code generator」というテンプレートを選択します。
  • (2) Activate
    プロジェクトの配置先を指定(C:\pleiades\work)して、「Create」ボタンでActivateします。

TypesafeActivator-selected.png

以上で、Slickのコードジェネレータを実行するプロジェクトが生成されました。

5. ソースコードのジェネレート

プロジェクトが生成されると自動的にコンパイルが実行され、サンプルデータベーススキーマに対するソースコードジェネレートが実行されます。どのように生成されたのかを確認してみましょう。
メニューから「Code」を選択するとソースコードを閲覧・編集することが出来ます。

TypesafeActivator-code.png

「Browse code」から「project」->Build.scalaの順に選択し、Build.scalaを開いてみましょう。コンパイル時に「slickCodeGenTask」が実行され、ソースコードをジェネレートするように設定されています。

Build.scala (/project)

サンプルのデータベーススキーマからソースコードが生成できるように設定してあります。では、続いて、生成されたソースコードを確認してみましょう。以下のディレクトリに生成されています。

  • target/scala-2.10/src_managed/slick/demo

「Code」を選択し、ホームボタンでプロジェクトルートディレクトリに移動し、「target」からパッケージを順に選択していき、「Tables.scala」を開いてみましょう。これが、ジェネレートされたファイルです。

続いて、今回のアプリケーションで使用するデータベーススキーマに対してジェネレートしてみます。先ほど開いた「Build.scala」に記述しているデータベース接続情報を修正します。

Build.scala (/project)

ファイルを編集したら、右上の「Save」ボタンで保存します。

TypesafeActivator-Save1.png

メニューから「Compile」を選択し、「Start compiling」をクリックしコンパイルを実行するとソースコードが生成されます。そこで、以下のようにコンパイルエラーが発生します。

TypesafeActivator-CompileError.png

「Tables.scala」を利用するサンプルクラス「Example.scala」がサンプルスキーマに合わせて実装されているためです。今回使用するデータベーススキーマに合わせて修正しておきましょう。(修正しなくてもジェネレート自体には影響ありません。)

Example.scala (/src/main/scala)

保存すると自動的にコンパイルが実行されます。コンパイル結果(ログ)は、メニューから「Compile」を選択すると確認できます。エラーが発生していないことを確認しておきましょう。

TypesafeActivator-CompileNoError.png

コンパイルが成功すると自動的にアプリケーションが実行されます。実行時のログは、メニューから「Run」を選択すると確認することが出来ます。実行されたのは先ほど修正した「Example.scala」で、自動生成されたソースコードを利用し、Eventテーブルの内容をコンソール出力するだけの単純なアプリケーションです。

TypesafeActivator-Run.png

コンパイルによりソースコードのジェネレートも実行されているはずなので、出力先(/target/scala-2.10/src_managed/slick/models)を確認してみましょう。「Tables.scala」が生成されました。このように、Slickコードジェネレータはsbtからも実行することができ、実行環境の構築には「Typesafe Activator」が非常に便利です。

「Typesafe Activator」には「2.起動」のトップ画面で御覧頂いたとおり、様々なプロジェクトテンプレートが準備されており、 「Typesafe.com」のTYPESAFE ACTIVATOR/TEMPLATES から用途にあったテンプレートを探すことが出来ます。例えば、Playのアプリケーションを開発するときには、「Hello Play Framework!」を、Akkaを利用するには「Hello Akka!」を使用し、ブランクプロジェクトを作成します。執筆時点では、108個のテンプレートが用意されおり、新たなテンプレートをコントリビュートすることも出来ます。手順は 「Typesafe.com」のTYPESAFE ACTIVATOR/CONTRIBUTE TEMPLATE を参考にしてください。

更に、「Typesafe Activator」ではEclipseプロジェクトに変換するところまでWebブラウザで操作することが出来ます。Eclipseプロジェクトへの変換は、メニューから「Code」を選択し、「Browse code」の右上のボタンから「Open project in Eclipse」を選択します。

TypesafeActivator-Eclipse1.png

「Generate them now」をクリックするとEclipseプロジェクトファイルが作成されます。

TypesafeActivator-EclipseCreate.png

あとはEclipseにインポートするだけで簡単に開発をスタートすることが出来ます。

今回はSlickのコードジェネレータと「Typesafe Activator」を紹介しました。次回は、今回作成したアプリケーションを利用して、トランザクション制御の実装方法について紹介したいと考えています。

エンジニア採用中!私たちと一緒に働いてみませんか?