GRAILS導入メモ(1)
ソフトウェアバージョン
- OS: CentOS 6.0 (64bit)
- Java SDK: Java6 update 27 (http://www.oracle.com/technetwork/java/javase/downloads/index.html)
- Groovy: GRAILSに同梱のもの 1.7.8
- GRAILS: Grails 1.3.7 (http://grails.org/)
導入手順
Java SDK
# rootユーザで実施 #### #### RPM版をインストール #### # JavaSDK: /usr/java/jdk1.6.0_27 にインストールされる # JavaDB(Derby): /opt/sun/javadb にインストールされる ./jdk-6u27-linux-x64-rpm.bin # 解凍されてできたRPMを削除 rm jdk-*.rpm sun-javadb-*.rpm #### #### 環境変数 JAVA_HOME 設定 #### echo "export JAVA_HOME=/usr/java/default" > /etc/profile.d/java.sh
GRAILS
# rootユーザで実施 (一般ユーザの方がいいのか?) #### #### インストール #### # ディレクトリ作成 mkdir /opt/grails cd /opt/grails # 解凍 unzip /root/grails-1.3.7.zip # リンク作成 ln -s grails-1.3.7 default #### #### 環境変数 GRAILS_HOME 設定 #### echo "export GRAILS_HOME=/opt/grails/default" >> /etc/profile.d/grails.sh echo 'pathmunge $GRAILS_HOME/bin' >> /etc/profile.d/grails.sh #### #### 動作確認 #### # ログインしなおして環境変数を反映してから・・・ grails # 下記が出力されればよい # Welcome to Grails 1.3.7 - http://grails.org/ # Licensed under Apache Standard License 2.0 # Grails home is set to: /opt/grails/default # # No script name specified. Use 'grails help' for more info or 'grails interactive' to enter interactive mode
クイックスタートを実施してみる
GRAILSアプリの生成
# GRAILSのアプリを入れるディレクトリを作成 mkdir /grails # GRAILSのアプリ生成 cd /grails grails create-app my-project # 下記が出力されればよい # Welcome to Grails 1.3.7 - http://grails.org/ # Licensed under Apache Standard License 2.0 # Grails home is set to: /opt/grails/default # # Base Directory: /grails # Resolving dependencies... # Downloading: /opt/grails/default/lib/gpars-0.9.jar ... # Download complete. # # ・・・(中略)・・・ # # Installed plugin tomcat-1.3.7 to location /root/.grails/1.3.7/projects/my-project/plugins/tomcat-1.3.7. ... # Executing tomcat-1.3.7 plugin post-install script ... # Plugin tomcat-1.3.7 installed # Plugin provides the following new scripts: # ------------------------------------------ # grails tomcat # Created Grails Application at /grails/my-project
生成後のディレクトリ構成
こんなことになっていた。
/grails └── my-project ├── grails-app │   ├── conf │   │   ├── hibernate │   │   └── spring │   ├── controllers │   ├── domain │   ├── i18n │   ├── services │   ├── taglib │   ├── utils │   └── views │   └── layouts ├── lib ├── scripts ├── src │   ├── groovy │   └── java ├── test │   ├── integration │   └── unit └── web-app ├── css ├── images │   └── skin ├── js │   └── prototype ├── META-INF └── WEB-INF └── tld
Domain Class作成
# 作成 cd /grails/my-project grails create-domain-class org.example.Book # 下記が出力されればよい # Welcome to Grails 1.3.7 - http://grails.org/ # Licensed under Apache Standard License 2.0 # Grails home is set to: /opt/grails/default # # Base Directory: /grails/my-project # Resolving dependencies... # Dependencies resolved in 3939ms. # Running script /opt/grails/default/scripts/CreateDomainClass.groovy # Environment set to development # [mkdir] Created dir: /grails/my-project/grails-app/domain/org/example # Created DomainClass for Book # [mkdir] Created dir: /grails/my-project/test/unit/org/example # Created Tests for Book # 作成されたファイルを除いてみる cat /grails/my-project/grails-app/domain/org/example/Book.groovy # package org.example # # class Book { # # static constraints = { # } # }
Domain Class編集
package org.example class Book { String title String author // validation 的なものらしい (not null 制約的な) static constraints = { title(blank: false) author(blank: false) } }
Controller 作成
# 作成 cd /grails/my-project grails create-controller org.example.Book # 下記が出力されればよい # Welcome to Grails 1.3.7 - http://grails.org/ # Licensed under Apache Standard License 2.0 # Grails home is set to: /opt/grails/default # # Base Directory: /grails/my-project # Resolving dependencies... # Dependencies resolved in 2408ms. # Running script /opt/grails/default/scripts/CreateController.groovy # Environment set to development # [mkdir] Created dir: /grails/my-project/grails-app/controllers/org/example # Created Controller for Book # [mkdir] Created dir: /grails/my-project/grails-app/views/book # Created Tests for Book # 作成されたファイルを除いてみる # 名前が *Controller であることは重要らしい(それでコントローラを見つけるとかなんとか・・・これがCoCの一端か) cat /grails/my-project/grails-app/controllers/org/example/BookController.groovy # package org.example # # class BookController { # # def index = { } # }
Controller 編集
scaffoldでCRUD処理を簡単にできるコードを生成してもらえるということか・・・?
package org.example class BookController { def scaffold = Book }
起動
あれ、コントローラに対して常にVIEWを作らなければいけないんじゃ・・・。それをscaffoldで生成してくれるんだろうか。まぁとりあえず書かれている通りに起動しよう。GRAILSに同梱されているTomcatが起動されるらしいから。
cd /grails/my-project/ grails run-app # 下記が出力されればよい # Welcome to Grails 1.3.7 - http://grails.org/ # Licensed under Apache Standard License 2.0 # Grails home is set to: /opt/grails/default # # Base Directory: /grails/my-project # Resolving dependencies... # Dependencies resolved in 3466ms. # Running script /opt/grails/default/scripts/RunApp.groovy # # ・・・(中略)・・・ # # Running Grails application.. # Server running. Browse to http://localhost:8080/my-project # ホスト名に対応するエントリを hosts に入れていなかったら、下記のエラーが出た。 # エントリを追加したら解消。 # 2011-08-28 11:33:11,879 [main] ERROR ehcache.Cache - Unable to set localhost. # This prevents creation of a GUID. Cause was: lvmel6003: lvmel6003 # java.net.UnknownHostException: lvmel6003: lvmel6003 # at java.net.InetAddress.getLocalHost(InetAddress.java:1360) # ・・・長大なスタックトレース(略)・・・
ブラウザからアクセス
http://x.x.x.x:8080/my-project
上画面の org.example.BookController をクリックすると
http://x.x.x.x:8080/my-project/book/list
再起動すると登録した本は消えていた
永続化のためのDB設定とかは一切やってないからなぁ。というか起動中はどこに保存していたんだ・・・メモリ?
What's Next を実施してみる
先ほどの永続化関連の疑問にもここである程度答えがわかるようだ・・・
BootStrapにアプリケーション起動時にしたいことを追加する
追加先は /grails/my-project/grails-app/conf/BootStrap.groovy で、初期状態では何も処理していない。
init がアプリケーション起動時に実行するクロージャ、destroy が停止時に実行するクロージャ。
このぐらいなら普通にメソッドにして呼んでも良さそうだが、あえてクロージャになってるのは何故なんだろう。
class BootStrap { def init = { servletContext -> } def destroy = { } }
Book テーブルにレコードが存在しない場合のみ、レコードを追加する処理を入れる。
import org.example.Book class BootStrap { def init = { servletContext -> // Bookテーブル内のレコード数はこれでとれてしまう if (!Book.count()) { // failOnError が指定されていると永続化の保存に失敗した場合に Exception を投げる // デフォルトだと save() は失敗時に null を返して Exception は投げない new Book(author: "Stephen King", title: "The Shining").save(failOnError: true) new Book(author: "James Patterson", title: "Along Came a Spider").save(failOnError: true) } } def destroy = { } }
起動し直してみると、最初からたしかに2レコードが表示される。
起動にかかる時間は30秒程度。結構起動は時間がかかる印象だが、実際使う場合はアプリケーションのホットデプロイとかでできるんでしょう?ということで特に問題ではないと思っている。
DataSource を変更して、揮発しないDBにしてみる(初期状態確認)
DataSource の設定は /grails/my-project/grails-app/conf/DataSource.groovy にある。
- 初期状態は HSQLDB のin-memoryデータベースに接続するようになっている。
- grails run-app 実行時に 『Environment set to development』が出力されるので、environments の development の設定内容が反映されていると思われる。開発・試験・本番で設定が選べそうなのは嬉しい。どこでスイッチできるのかは今は不明だが・・・。
- dbCreate はテーブルの作成・削除有無を制御する。
- environment/development/datasource/dbCreate = "update" にしてみたが、揮発状態は変わらず。environment/development/datasource/url = "jdbc:hsqldb:mem:devDB" がin-memoryデータベース指定だから変わるわけもなく。
dataSource { pooled = true driverClassName = "org.hsqldb.jdbcDriver" username = "sa" password = "" } hibernate { cache.use_second_level_cache = true cache.use_query_cache = true cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider' } // environment specific settings environments { development { dataSource { dbCreate = "create-drop" // one of 'create', 'create-drop','update' url = "jdbc:hsqldb:mem:devDB" } } test { dataSource { dbCreate = "update" url = "jdbc:hsqldb:mem:testDb" } } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } } }
DataSource を変更して、揮発しないDBにしてみる(HSQLDB ファイル編)
mkdir /grails/db でDB保存先を作成し、下記のように変更してみると、再起動しても揮発しない状態にできた。
// environment specific settings development { dataSource { //dbCreate = "create-drop" // one of 'create', 'create-drop','update' //url = "jdbc:hsqldb:mem:devDB" dbCreate = "update" url = "jdbc:hsqldb:file:/grails/db/devDB" } }