本文是对Grails 1.2.x 至 1.3.7版本之间主要的新特性做了一个汇总,以便于学习和查阅。如果有新版本发布,还会持续更新。
参考文档:http://grails.org/Release+Notes
框架、配置等
------------------------------------------
可以重新加载预编译的GSP,包括i18n也会重新加载。
在Config.groovy中设置:
grails.gsp.reload.enable = true
处于性能原因,建议在生产环境中关闭config.groovy中的grails.logging.jul.usebridge参数。
全局应用程序布局(config.groovy中):
grails.sitemesh.default.layout='myLayoutName'
可以在resource.groovy中直接访问应用程序的实例,比如:
import grails.util.* beans = { if (application.config.my.company.mockService) { myBean(my.company.mock.MockImpl) { bookService = ref("bookService") } } else { myBean(my.company.MyBeanImpl) { bookService = ref("bookService") } } }
可以在BuildConfig.groovy中设置Tomca JVM的参数:
grails.tomcat.jvmArgs = ["-Xmx1024m", "-XX:MaxPermSize=256m"]
通过run-script运行多个Groovy脚本:
grails run-script [path-to-script-1] [path-to-script-2]...[path-to-script-n]
出于安全考虑,Grails日志信息可以用以下配置排除记录请求参数中的敏感信息:
grails.exceptionresolver.params.exclude = ['password', 'creditCard']
或者干脆通过配置grails.exceptionresolver.logRequestParameters参数禁止日志记录请求参数。
grails.exceptionresolver.logRequestParameters = false
视图、Web标签
------------------------------------------
link标签可以支持attr属性:
<link:accountDetails attrs="[class: 'fancy']" acctNumber="8675309">Show Account</link:accountDetails>
结果是
<a href="/details/8675309" class="fancy">Show Account</a>
新的标签unless,与if标签类似:
<g:unless test="${cacheEnabled}"> Tag Body Goes Here </g:unless>
新的join标签:
<g:join in="['Grails', 'Groovy', 'Gradle']" delimiter="_"/>
结果是:
Grails_Groovy_Gradle
GORM
------------------------------------------
GORM支持beforeValidate
class Person { String name static constraints = { name size: 5..45 } def beforeValidate() { name = name?.trim() } }
查询支持排序:
Person.recentPublications.list(sort: 'title', order: 'desc', ignoreCase: true)
.find方法和.findAll方法支持查询缓存:
def musicians = Musician.find('from Musician where name = :name', [name: 'Brian'], [cache: true]) Book.findAll("from Book as b where b.author=:author" , [author:'Dan Brown'], [cache: true ])
新的方法检查脏数据(对象是否改变)
def airport = Airport.get(10) assert !airport.isDirty() airport.properties = params if (airport.isDirty()) { // do something based on changed state }
包括检查单独的域(字段)
def airport = Airport.get(10) assert !airport.isDirty() airport.properties = params if (airport.isDirty('name')) { // do something based on changed name }