<!----><!----><!----> <!---->
Grails 1.1 Beta 2发布
2008 年 12 月 23日
SpringSource 和Grails 开发小组非常高兴的宣布Grails web application 开发框架的 1.1 beta 2 版本发布了.
Grails 是一个构建在Java 和Groovy 之上的动态web application framework ,利用Java EE 领域的最好的breed APIs 包括Spring, Hibernate 和 SiteMesh 。允许Java developers 利用他们使用多年的已有知识和被证实配置复杂的经历, Grails 给Java and Groovy 开发者带来了基于约定快速开发的乐趣。
关于此次发布的更多信息,请访问下面的链接:
下面介绍一下1.1 版本的新特性.
更好的GORM 事件 (Better GORM events )
之前, GORM 只支持 beforeInsert, beforeUpdate 和beforeDelete 事件, 现增加了afterInsert, afterUpdate 和afterDelete 来完成图片操作
Persistence of Collections of Basic Types 基本类型集的持久化
GORM 现在支持基本类型比如String, Integer 等使用一个连接表的持久化。
class Person { static hasMany = [nicknames:String] }
对象的只读访问Read-Only Access to Objects
现在,持久化实例对象可以使用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 的改进Improvements to Dynamic 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-manys 遗留映射Legacy Mapping for Unidirectional
单项的One-to-manys 关联关系可以使用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']
}
}
增强枚举类型的支持Enhanced Enum Support
现在,枚举类型使用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
多插件仓库Multiple Plugin Repositories
现在,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"
The Grails plugin discovery commands like list-plugin and install-plugin will then automatically work against all configured repositories. To release a plugin to a specific repository you can use the repository argument:
grails release-plugin -repository=myRepository
自动安装插件方案 Automatic Transitive Plugin Resolution
插件不再需要到SVN 检出,当应用程序第一次加载时,通过插件元数据会自动安装。
另外, plugin dependencies are now resolved transitively.
插件的作用范围和环境 Plugin Scopes and Environments
现在,插件可以作用于环境或预置的构建范围内:
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
}
}
属性子集的数据绑定Data Binding a Subset of Properties
It is now simpler to bind data to a subset of properties. Previously you could use the syntax:
person.properties = params
Which would bind all the incoming request parameters to the person. If you didn't want that behavior you could use the bindData method. Now you can bind to a subset of properties using the subscript operator:
person.properties["firstName","lastName"] = params
And access a subset of the domain classes properties using the same syntax:
person.properties["firstName","lastName"].each { println it }
集合类型的数据绑定Data Binding for Collection Types
Grails now supports data binding to collections types including lists, sets and maps.
<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" />
Grails will auto-instantiate domain instances at the given indices and the necessary values will be populated in the association.
模板和动态脚手架Templates and Dynamic Scaffolding
现在,动态脚手架使用通过install-templates 命令安装的模板 。
支持更多关联类型Support for more association types
现在,Scaffolding 支持 many-to-many 和单项的 one-to-many 关联.
<!----><!----> <!---->
在JSP 中支持JSP 标签库 JSP Tag library support in 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")}
工程基本结构(Project Infrastructure )
Grails 1.1 缘自和 Maven plugin 和archetype 的关联,允许你使用Maven 更容易的构建Grails 工程。根据操作指南 here 或使用原型来创建一个新的Grails 工程, 或运行:
mvn grails:create-pom
来为已有工程创建一个Maven POM.
环境及元数据API Environment and Metadata 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 配置的方式:
log4j = {
error 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages' // GSP
warn 'org.mortbay.log'
}
详见user guide 中Log4j DSL 全部文档。
灵活的构建配置 Flexible Build Configuration
新的 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
加密数据源 Encrypted Data Sources
现在,数据源密码可以使用已提供的编码类来加密:
dataSource {
username = "foo"
password = "438uodf9s872398783r"
passwordEncryptionCodec="my.company.encryption.BlowfishCodec"
}
支持的编码使用 Grails' 现存的 编码机制
Grails 1.1 有很多改变,但大多是向后兼容1.0.x 系列的。如果有问题请报告。升级时,以下是已知需要注意的问题列表:
grails -Dgrails.plugins.dir=./plugins run-app