Grails 1.1 Beta 2
發布了,Groovy
1.6 final
和Grails 1.1 final
也越來越近,不過已經不是很感興趣了。雖然對于Java
開發者來說,相比Rails
,Grails
更容易上手,但它并不成熟的。在論證
Grails
的成熟度時,Graema
說:“
你會把Spring
和Hibernate
看作風險嗎?” Spring
和Hibernate
確實不是風險,但Grails
對Spring
和Hibernate
的包裝卻是一個極大風險,“
在種種危險中,最主要的一點是我們已經對底層框架的抽象太成功了,以至于有時會出現問題。”
具體可以看看這個例子。使用Grails
,不如使用JRuby On Rails
或者Play!?
不管怎么樣下面介紹一下1.1版本的新特性:
?
GORM
更好的GORM事件
之前, GORM 只支持 beforeInsert, beforeUpdate 和beforeDelete 事件, 現增加了afterInsert,
afterUpdate 和afterDelete 來完成圖片操作
?
基本類型集的持久化
GORM 現在支持基本類型比如String,
Integer 等使用一個連接表的持久化。
class ?Person?{?? ?
static ?hasMany?=?[nicknames:String]?
}??
?
class Person {
?
?? static hasMany =
[nicknames:String]
?
}
?
對象的只讀訪問
現在,持久化實例對象可以使用read
方法以只讀狀態被加載:
def book = Book.read(1)
???????????????????????
默認的排列順序
現在,關聯可以使用一個類級別聲明的默認的排列順序來排序:
class Book {
? String title
? static mapping = {
???? sort "title"
? }
}
或在關聯級別上:
class Author {
??? static hasMany = [books:Book]
??? static mapping = {
?????????????
books sort:"title"
??? }
}
?
批處理
現在GORM 支持使用ORM DSL 在類級別上配置批處理(batch fetching )(
延遲加載的優化):
class Book {
? String title
? static mapping = {
???? batchSize 15
? }
}
或在關聯級別上:
class Author {
??? static hasMany = [books:Book]
??? static mapping = {
?????????????
books batchSize:15
??? }
}
?
動態Finders的改進
動態查詢器的新后綴InList
可用:
def groovyBooks = Book.findByAuthorInList(['Dierk Koenig',
'Graeme Rocher'])
現在,Dynamic
finders 也能查詢緩存:
def books = Book.findByTitle("Groovy in Action",
[cache:true] )
可以使用悲觀鎖:
def books = Book.findByTitle("Groovy in Action",
[lock:true] )
?
單項的One-to-many遺留映射
單項的One-to-many關聯關系可以使用joinTable 參數改變它們對底層數據庫的映射:
class Book {
? String title
? static belongsTo = Author
? static hasMany = [authors:Author]
? static mapping = {
???? authors joinTable
:[name:"mm_author_books", key:'mm_book_id' ]
? }
}
class Author {
? String name
? static hasMany = [books:Book]
? static mapping = {
???? books
joinTable:[name:"mm_author_books", key:'mm_author_id']
? }
}
?
增強枚舉類型的支持
現在,枚舉類型使用GORM
調用的getId ()方法來持久化枚舉狀態。
enum Country {
?? AUSTRIA('at'),
?? UNITED_STATES('us'),
?? GERMANY('de');
?? final String id
??? Country(String id) { this.id = id }
}
?
插件
全局插件
現在,安裝插件可以給所有的應用程序共享:
grails install-plugin webtest -global
?
多插件倉庫
現在,Grails 支持通過提供多插件倉庫配置的能力
使用USER_HOME/.grails/settings.groovy
文件或包含配置好的倉庫詳情的grails-app/conf/BuildConfig.groovy
文件。
grails.plugin.repos.discovery.myRepository="http://svn.codehaus.org/grails/trunk/grails-test-plugin-repo"
grails.plugin.repos.distribution.myRepository="https://svn.codehaus.org/grails/trunk/grails-test-plugin-repo"
Grails的插件命令如list-plugin和install-plugin會自動使用所有設置的插件倉庫,發布一個插件到一個插件倉庫可以是用下面的命令:
grails release-plugin -repository=myRepository
?
自動安裝插件方案
插件不再需要到SVN 檢出,當應用程序第一次加載時,通過插件元數據會自動安裝。另外,插件的依賴關系問題已經解決了。
?
插件的作用范圍和環境
現在,插件可以作用于環境或預置的構建范圍內:
def environments = ['dev', 'test']
def scopes = [excludes:'war']
僅在那些環境中加載使用,而不打包到WAR
文件中。這使得產品使用時
"development-only" 的插件不會被打包。
?
測試
測試框架
現在,作為1.0.x 系列可用插件的新測試框架已集成到 Grails 1.1.
該測試框架增加了模擬所以普通類型包擴控制器,領域類,標簽庫和url
映射簡寫的行為,快速運行單元測試。
class SongTests extends grails.test.GrailsUnitTestCase {
??? void testMinimumDuration() {
??????? mockDomain(Song)
??????? def song = new
Song(duration: 0)
??????? assertFalse
'validation should have failed', song.validate()
??????? assertEquals
"min", song.errors.duration
??? }
}
?
數據綁定
屬性子集的數據綁定
現在更容易對屬性的自己和進行數據綁定。在之前的版本中你也許會使用:
person.properties?=?params??
?
這將會將request中的所有變量綁定到person中。如果你不想綁定所有的數據的話,你可以使用 bindData
方法。現在你可以通過使用subscript operator來綁定部分的變量:
?
person.properties["firstName","lastName"]?=?params??
person.properties["firstName","lastName"]
= params
?
要取得domain中的所有屬性的一個子集也可以通過這樣的方式:
person.properties["firstName","lastName"].each?{?println?it?}?
?
集合類型的數據綁定
Grails已經支持集合類型的數據綁定,例如list、set和map。
<g:textField name="books[0].title"
value="the Stand" />
<g:textField name="books[1].title"
value="the Shining" />
<g:textField name="books[2].title"
value="Red Madder" />
?
腳手架
模板和動態腳手架
現在,動態腳手架使用通過install-templates
命令安裝的模板。
?
支持更多關聯類型
現在,Scaffolding
支持 many-to-many 和單項的 one-to-many 關聯。

Groovy Server Pages
在JSP中支持JSP標簽庫
現在,GSP 已經支持JSP 標簽庫復用的能力:
<%@ taglib prefix="fmt"
uri="http://java.sun.com/jsp/jstl/fmt" %>
<fmt:formatNumber value="${10}"
pattern=".00"/>
JSP 標簽也可以像正常的GSP 標簽一樣調用:
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"
%>
${fmt.formatNumber(value:10, pattern:".00")}
?
工程基本結構
Maven 集成?
Grails 1.1 緣自和
Maven plugin 和archetype 的關聯,允許你使用Maven 更容易的構建Grails
工程。根據操作指南here或使用原型來創建一個新的Grails 工程,
或運行:
mvn grails:create-pom
來為已有工程創建一個Maven
POM.
?
環境及元數據API??
使用新 API 來訪問當前環境:
import grails.util.Environment
...
switch(Environment.current) {
??????? case
Environment.DEVELOPMENT:
??????? ??
configureForDevelopment()
??????? break
??????? case
Environment.PRODUCTION:
??????? ??
configureForProduction()
??????? break
}
當然也有一個易于訪問應用程序元數據的新類:
def metadata = grails.util.Metadata.current
println metadata.applicationName
println metadata.applicationVersion
?
Log4j
DSL??
新的 Log4j DSL 用于替換以前Log4j 配置的方式:
log4j = {
??? error?
'org.codehaus.groovy.grails.web.servlet',? //? controllers
???????
?????? 'org.codehaus.groovy.grails.web.pages'
//? GSP
??? warn?? 'org.mortbay.log'
}
詳見user guide 中Log4j DSL 全部文檔。
?
靈活的構建配置
新的
grails-app/conf/BuildConfig.groovy 文件可用,它允許你配置不同層面的Grails
構建輸出路徑和服務器使用插件的解決方案:
grails.work.dir="/tmp/work"
grails.plugins.dir="/usr/local/grails/plugins"
grails.project.test.reports.dir="/usr/local/grails/test-reports"
?
非交互模式?
現在,Grails 支持一種--non-interactive flag ,須鍵入到命令行,目的是關閉用戶提示:
grails run-app --non-interactive
這對服務器持續集成是有幫助的。
?
加密數據源?
現在,數據源密碼可以使用已提供的編碼類來加密:
dataSource {
?????? username =
"foo"
?????? password =
"438uodf9s872398783r"
?????? passwordEncryptionCodec="my.company.encryption.BlowfishCodec"
}
支持的編碼使用
Grails' 現存的編碼機制。
?
升級備注
Grails 1.1 有很多改變,但大多是向后兼容1.0.x
系列的。如果有問題請報告。升級時,以下是已知需要注意的問題列表:
Plugins 不保存在你的
USER_HOME 路徑下. 你需要重寫安裝插件或運行:
????? grails
-Dgrails.plugins.dir=./plugins run-app
現在枚舉類型已經被映射到數據庫,使用字符串值而不是原始默認的。
jsession id 默認已無效.
詳見GRAILS-3364
GSP 空白符處理已經變好很多了,比以前有更多空白符.
詳見GRAILS-3277
grails.testing.reports.destDir 配置選項已被替代為grails.project.test.reports.dir
現在,PreInit.groovy
改為BuildConfig.groovy
控制器中的allowedMethod
屬性被標識為static 。非 static 版本不推薦使用,盡管它仍然起作用并在控制臺產生信息。
?
Grails1.0的這篇文章也可以作為參考。