grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
DESCRIPTION
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 新機能などの紹介。2009/12/8 Japan Grails Groovy Users Group G*ワークショップ 7 at TokyoTRANSCRIPT
Grails 1.2 探検隊新たな聖杯をもとめて・・・
JGGUGjapan grails/groovy user group
def speaker = new Cast(name:”T.Yamamoto”,version:”G*-2009-12-18”)
はじめに年末までにリリース予定のGrails-1.2の新機能を時間いっぱいひたすら紹介します。但し時間が無くなり次第紹介終了となります。
おまけつきです。
紹介やまもとです。職種:テクニカルDTP
twitter: @tyamaはてな id: mottsniteブログも↑
「Grails徹底入門」共著 9~11を執筆 Grailsプラグインの人
日本 Grails/Groovy ユーザーグループhttp://www.jggug.org/
Grails 1.2.0ロードマップによるとコードネーム「ベディヴィエール」
ちなみに、2.0は、「ガラハッド」
円卓の騎士なんですね!
そんな事は
どうでもいい!
Grails 1.2.0Spring 3.0 サポート。デフォルトコンテナをTomcatに変更。スタンドアロンGSP。Web Flowをプラグインにする。キー依存の更新。プラグインのドキュメント生成の改善。GSPのプリコンパイルコアの改善名前付きURLマッピング
- http://grails.org/Roadmap
Grails 2.0プラグインでのモジュラー開発を次のレベルへ:OSGiの対応
プラグインをOSGiバンドルへのパッケージ機能。プラグインの叙述的な依存宣言機能。ジェネリックセキュリティキャッシュ戦略、制約等のセンシブルデフォルトをオーバーライド可能に。
- http://grails.org/Roadmap
その前に、1.3があるよ!
Grails-1.2Grails 1.2 M1Grails 1.2 M2Grails 1.2 M3Grails 1.2 M4Grails 1.2 RC1Grails 1.2 RC2
1.2 M11.2-M1 2009/6/29Warデプロイの際にGSPプリコンパイル名称付きURLマッピングプロジェクト用ドキュメントエンジン Pt.1プラグインメタデータジェネレータ
1.2 M21.2-M2 2009/8/11Spring3に更新URI Re-writing onto any URI@Transactionalでのメソッド単位のトランザクションの実装 (spring3関連)GORM ダイナミックファインダでのBoolean値の機能を追加 Pt.1GORMにhasOneマッピングをサポートドメインクラスで名前付き問合せ定義が可能にPt.1GORM 厳密なバリデーションエラーi18nでのクラス名プロパティ名をハンドルマルチ組込コンテナサポート、デフォルトはTomcatデザインリニューアル
1.2 M31.2-M3 2009/10/2依存解決DSLGSPパフォーマンスの超最適化Webフローをプラグイン化(外部化) Pt.1ZipのみのプラグインリリースformatNumberとformatDate タグの改良
1.2 M41.2-M4 2009/11/6BootStrap に環境指定。GORMデフォルト値のグローバル定義Webフローのプラグイン化(外部化)の追加実装 Pt.2Better JSONBuilder
1.2 RC11.2-RC1 2009/12/4grails install-dependencyコマンドドメインクラスでの名前付き問い合わせ Pt.2CriteriaビルダーでsqlRestriction実装ドメインクラスのアノテーションエンティティ関連paramsとタグのattrsに便利なnullセーフコンバータが追加された。プロジェクトドキュメントエンジン 外部利用可能Config.groovy(又は外部ファイル定義)でビーンのプロパティオーバライドで文字型以外の型に対応テスト関連の改良テストフェーズとターゲット指定テストの前にクリーン強制実行System.outとSystem.errをエコーさせる。
1.2 RC21.2-RC2 2009/12/16spring-3.0 RELEASE に更新安定に向けてRC1のバグフィックス!
最終のリリース予定は来週です。
多い・・・
せめて項目別に・・・
Grails-1.2 項目分けしてみたコア、デザイン、コンテナ
ドキュメント生成エンジン
GSP、View
マッピング、コントローラ、サービス
ドメイン、GORM
ライブラリ管理
プラグイン
テスト
コア、デザイン、コンテナSpring3に更新
デザインリニューアル
マルチ組込コンテナサポートデフォルトはTomcat
Spring-3 に更新spring-3.0 RELEASE が入ってます。そして共存できる。例えば以下のSpring-MVCのコントローラ
package my.domainimport org.springframework.stereotype.*import org.springframework.web.bind.annotation.*import org.springframework.beans.factory.annotation.*import org.hibernate.*import org.springframework.ui.*
@Controllerclass HelloController {
@Autowired SessionFactory sessionFactory @RequestMapping("/hello.dispatch") ModelMap handleRequest() { def session = sessionFactory.getCurrentSession() println "hit" return new ModelMap(session.get(Person, 1L)) }}
HelloController.groovy
beans = { xmlns context:"http://www.springframework.org/schema/context" context.'component-scan'( 'base-package' :"my.domain" )}
resources.groovy
この設定で動きます。
<h1 id="hello">こにちわ! ${person.name}</h1>
hello.gspjspもOK。
デザインデザインリニューアル
サーブレットコンテナマルチ組込コンテナTomcat,jetty,glassfish(何処へ?)等の組込できるサーブレットコンテナをプラグイン化
Tomcat/Jettyプラグインを参考に!grails.web.container.EmbeddableServerFactorygrails.web.container.EmbeddableServer
コンテナ入れかえは、プラグインを入れかえるだけ!% grails uninstall-plugin tomcat% grails install-plugin jetty
デフォルトはTomcatJNDIConfig.groovygrails.naming.entries = [foo:"bar"]
resources.groovybeans = { xmlns jee:"http://www.springframework.org/schema/jee" jee.'jndi-lookup'(id:"foo", 'jndi-name':"java:comp/env/foo")}
リモートデプロイgrails tomcat deploygrails tomcat undeploy
設定は、Config.groovy (tomcat-users.xmlの設定もしてね)tomcat.deploy.username="manager"tomcat.deploy.password="secret"tomcat.deploy.url="http://myserver.com/manager"
リストも実行できますgrails tomcat list
ドキュメントエンジン外部利用も可能build.groovyファイル http://gist.github.com/258552 テンプレはGRAILS_HOME/src/grails/doc からコピー
@Grapes([ @Grab("org.grails:grails-docs:1.2.0.RC2"), @Grab("radeox:radeox:1.0-b2"), @Grab("ant:ant-nodeps:1.6.5"), @GrabConfig(systemClassLoader=true)])import grails.doc.ant.*new AntBuilder().sequential { native2ascii(src:"conf",dest:"src/docs", includes:"**/*.properties",encoding:"UTF-8") taskdef(name:'docs',classname:'grails.doc.ant.DocPublisherTask') docs(src:"src/docs", dest:"build/docs", properties:"src/docs/doc.properties", styleDir:new File('src/resources/style'), cssDir:new File('src/resources/css'), imagesDir:new File('src/resources/img') )}
Directory
GSP、ビューWARデプロイでのGSPプリコンパイル
GSPパフォーマンスの超最適化
paramsとタグのattrsに便利なnullセーフコンバータが追加された。
formatNumberとformatDateタグの改良
i18nでのScaffold時のパーツ名称を定義
GSP、ビューWARデプロイでのGSPプリコンパイルGSPパフォーマンスの超最適化
grails war で書きだして解凍してみた
Grails-1.1.x Grails-1.2
GSP、ビューparamsとタグのattrsに便利なnullセーフコンバータが追加された。
formatNumberとformatDate タグの改良いろいろオプション増えました。詳しくはドキュメントを参照!
//int('パラメータ名')とかlong('パラメータ名')とかboolean('パラメータ名')と付けるdef total = params.int('total')//同じ名称のパラメータをリスト型にまとめるdef names = params.list('names')
def foo = { def hoge = params.some if(hoge) println hoge.toInteger()} someに文字列きたらエラー
def foo = { def hoge = params.long('some') if(hoge) println hoge.toInteger()}
params.long('some')で回避
messages_*.propertiesに記述http://gist.github.com/258601
default.paginate.prev=戻るdefault.paginate.next=次へdefault.boolean.true=はいdefault.boolean.false=いいえdefault.date.format=yyyy/MM/dd HH:mm:ss zdefault.number.format=0
default.created.message={0}(id:{1})を作成しました。default.updated.message={0}(id:{1})を更新しました。default.deleted.message={0}(id:{1})を削除しました。default.not.deleted.message={0}(id:{1})は削除できませんでした。default.not.found.message={0}(id:{1})は見つかりませんでした。default.optimistic.locking.failure=この{0}は編集中に他のユーザによって先に更新されています。
default.home.label=ホームdefault.list.label={0}リストdefault.add.label={0}を追加default.new.label={0}を新規作成default.create.label={0}を作成default.show.label={0}詳細default.edit.label={0}を編集
default.button.create.label=作成
i18nでのScaffold時のパーツ名称を定義
マッピング、コントローラ、サービス関連Better JSONBuilder
名称付きURLマッピング
URI Re-writing onto any URI
@Transactionalでのメソッド単位のトランザクションの実装
Config.groovy(または外部ファイル定義)でビーンのプロパティオーバライドで文字型以外の型に対応
BootStrapに環境指定
Better JSONBuilderこう書くと
こんなJSONが生成されます。
以前のバージョンの方式を使用する場合は、Config.groovyに、grails.json.legacy.builder=true
render(contentType:"text/json") { categories = [ { a = "A" }, { b = "B" } ] }
{"categories":[ {"a":"A"} , {"b":"B"}] }
マッピング、コントローラ、サービス関連名称付きURLマッピング
URIリライティング設定どのURIでも可能例: HelloControllerのマッピングへ
name productDetail:"/showProduct/$productName/$flavor?"{ controller = "product" action = "show"}
<link:productDetail productName="licorice" flavor="strawberry"> Strawberry Licorice </link:productDetail>
"/hello"(uri:"/hello.dispatch")
メソッド単位のトランザクション@Transactionalでメソッド単位のトランザクションが可能になりました。Springのアノテーションを使用します。org.springframework.transaction.annotation.Transactional
import org.springframework.transaction.annotation.*class BookService { @Transactional(readOnly = true) def listBooks() { Book.list() } @Transactional def updateBook() { // … }}
マッピング、コントローラ、サービス関連Config.groovy(または外部ファイル定義)でビーンのプロパティオーバライドで文字型以外の型に対応
beans { someService { someProperty = new SomeObject() }}
Config.groovy
マッピング、コントローラ、サービス関連BootStrap.groovyで環境の指定ができるようになりました
def init = { ServletContext ctx -> environments { production { ctx.setAttribute("env", "prod") } development { ctx.setAttribute("env", "dev") } } ctx.setAttribute("foo", "bar")}
BootStrap.groovy
ドメイン、GORM関連GORM ダイナミックファインダでのBoolean値の機能を追加GORMにhasOneマッピングをサポートドメインクラスで名前付き問合せ定義(Named Query Support†)GORM 厳密なバリデーションエラーGORMデフォルト値のグローバル定義CriteriaビルダーでsqlRestriction実装ドメインクラスのアノテーションエンティティi18nでのクラス名プロパティ名を定義
ダイナミックファインダでのBoolean値ダイナミックファインダでのBoolean値は、フィード名 または Notフィールド名を使用できます!
class Book { String title String author Boolean paperback }
Book.findAllPaperbackByAuthor("夏目漱石")
Book.findAllNotPaperbackByAuthor("夏目漱石")
hasOneマッピングをサポート双方向OneToOneで子側に外部キーを持つ hasOne
class Person { String name static hasOne = [address: Address]}class Address { String street String postCode Person person}
create table address ( id bigint ... , version bigint not null, person_id bigint not null, street varchar(255) not null, post_code varchar(255) not null, primary key (id), unique (person_id))create table person ( id bigint ... , version bigint not null, name varchar(255) not null, primary key (id))
名前付き問合せ(Named Query Support)namedQueries にDSLを定義
使用方法
class Publication { String title Date datePublished
static namedQueries = { recentPublications { def now = new Date() gt 'datePublished',now-365 } publicationsWithBookInTitle { like 'title','%Book%' } }}
def list = Publication.recentPublications.list()def list = Publication.recentPublications.list( max: 10, offset: 5)Publication.recentPublications.count()
厳密なバリデーションエラーsave()メソッドに、引数としてfailOnError:trueを付けるとValidationExceptionを返す
try { book.save(failOnError:true)}catch(ValidationException e) { // handle}
デフォルト値のグローバル定義GORMで使用する共通定義をデフォルト値としてConfig.groovyに設定
grails.gorm.default.mapping = { cache true id generator:'sequence' 'user-type'( type:org.hibernate.type.YesNoType,class:Boolean )}
シーケンスの定義
grails.gorm.default.constraints = { '*'(nullable:true, blank:false, size:1..20)}
共通利用したい制約
grails.gorm.default.constraints = { myConstraints(nullable:true, blank:false, size:1..20)}
制約グループ名を定義
static constraints = { myProperty shared:"myConstraints"}
ドメインクラスで使用する
CriteriaビルダーでsqlRestriction実装def c = Person.createCriteria()def peopleWithShortFirstNames = c.list { sqlRestriction "char_length( first_name ) <= 4"}
アノテーションエンティティgrails-app/domains内にあるドメインクラスにGORMシンタックスの代わりにアノテーションでも定義できます
import javax.persistence.*
@Entity@Table(name = "animal")class Animal {
@Id @GeneratedValue int id String name @ManyToOne @JoinColumn Owner owner
static constraints = { name blank:false }}
i18nでのクラス名プロパティ名を定義messages_*.propertiesに記述
chat.label=チャットchat.message.label=メッセージchat.name.label=名前chat.id.label=認識コードchat.dateCreated.label=作成日chat.lastUpdated.label=更新日
ライブラリ管理ライブラリ依存関係管理用DSL
grails install-dependencyコマンドローカルキャッシュにライブラリをインストールするコマンド
% grails install-dependency net.homeip.yusuke:twitter4j:2.0.9
grails.project.dependency.resolution = { ... repositories { //リポジトリ定義 mavenRepo "http://repository.codehaus.org" } dependencies { runtime 'net.homeip.yusuke:twitter4j:2.0.9' } ...} ローカルキャッシュ ls -al ~/.ivy2/cache
プラグインプラグインメタデータジェネレータメソッド追加などのメタ情報がplugin.xmlに生成される機能。IDE、ドキュメントエンジンから参照するもの。以下のコマンドで生成をスキップできます。
ZipのみのプラグインリリースGrailsプラグインをZipファイルだけ、(セントラル)プラグインリポジトリにリリースできるようになりました。SVN以外でプラグインバージョン管理している場合に有効。
% grails release-plugin --zipOnly
% grails release-plugin --skipMetadata
WebFlowプラグインWebフローをプラグイン化(外部化)†WebFlowを使う場合はプラグインインストール
onEntryやonRender等のイベント追加
% grails install-plugin webflow
def searchFlow = { onStart { println "started" } onEnd { println "ended" } displaySearchForm { onRender { println "rendering" } onEntry { println "entered" } onExit { println "exited" } on("submit") { [results: Book.findAllByTitle(params.title)] }.to "displayResults" } displayResults()}
テストテスト関連の改良:オーバーホール!
JUnitな実装でないテストツールも対応可能
System.outとSystem.errをエコーさせる。
デフォルトでは、テスト時は何も表示されない
-echoOutや-echoErrを指定で表示可能
% grails test-app -echoOut -echoErr
テストフェーズとターゲット指定grails test-app <phase>:<type>//‘spock’テストを‘unit’フェーズで実行grails test-app unit:spock
どちらもオプショナルです。//‘unit’フェーズで全てのタイプのテストを実行grails test-app unit://全てのフェーズで‘spock’テストを実行grails test-app :spock
‘SomeController’の全てのテストを ‘unit’フェーズで実行grails test-app unit: SomeController
‘unit’ と ‘integration’の全てのタイプのテストを実行grails test-app unit: integration:
従来の指定方法でも動きます。grails test-app unit:と同じですgrails test-app --unitテストの前にクリーン強制実行grails test-app -clean
おまけ
#GGXでのGrails 1.2トークをPodcastで見たまとめ
パフォーマンス依存解決プラグインでのモジュラリティPluggableTestフレームワーク名前付き問合せ・グローバル定義GSPプリコンパイル名前付きURLマッピングhasOneBetter Spring 統合Pluggableサーブレットコンテナ
パフォーマンス向上スループットが2,3倍に!GSPプリコンパイルでPermGenが減少
1秒間のリクエスト処理
PermGenが減少
1.0 1.1.x 1.2
1.0 1.1.x 1.2
今後の予定Flexインテグレーションの改良再利用可能なGORM-NoSQLアブストラクションGrails 2.0に向けてプラグインクラスローダの分離?
開発 vs デプロイ過去5年にくらべて開発は簡単になった。デプロイメントは変わっていない!変わらなくてはならない!
デプロイメントの複雑性
Virtualization 仮想化vmware仮想化はデプロイメントをGrailsの開発のようにシンプルにする。フレームワークを理解する仮想化。vmwareがGrailsを理解することができれば単純化できる。
例:数クリックで仮想化環境にデプロイ
クラウドとフレームワーククラウドはデプロイメントをシンプルできる可能性を持っているコンピュータのパワーをオンデマンドに提供Cloud Foundryでも既に提供しています。(バックエンドはAWS)
Internal vs External Cloudsエクスターナルクラウドは
柔軟ではないけど重要です。
インターナルクラウドはもっと説得力がある。
将来の話将来的にGrailsでのクラウドへのデプロイメントはこんな感じにできるようになるかもって話。grails deploy-to-cloud --app-servers=4 --db-servers=2
まとめ。更新内容お気に入りリスト!パフォーマンス向上!2-3倍!メモリに優しい
ドキュメントエンジン。外部利用可能
メソッド単位のトランザクション。細かな制御
Named Query Support まとめやすい!
GORMデフォルト値のグローバル定義. 共通利用
ドメインアノテーションエンティティ. GAE/J対策に!?
i18n対応の向上。CRUDで苦労しなくて良い
ぐれいるず
ほんとにりりーす?
クリスマス
ここで一句
正岡子規