内容节选---
Apress.Beginning.Groovy.and.Grails.From.Novice.to.Professional.Jun.2008
默认情况下,Groovy下的==就是equals方法,如果要进行对象比较,就需要使用is()方法
不过如果实现了Comparable接口,那么compareTo()方法会优先调用于equals方法
a**b 表示a的b次方
基础的断言
assert 1==2 : "One isn't Two"; //:后的信息会附加在异常中出现
org.codehaus.groovy.runtime.GStringImpl 要求"",且${}
'' 单引号无论是一行还是多行都会过滤掉${}
\ slashy
Method和Closure的区别在于 后者是对象,前者不是
默认情况下 Groovy下的集合为HashSet,也可以显式的声明为其他的格式
def emptySet = [] as Set
Set和List的区别在于不提供直接的下标索引提供查询,可以转as换成List后查询
Map 默认情况下是LinkedHashMap
def emptyMap = [:]
访问的方法比较多 ,eachWithIndex方法比较特别点
todos.eachWithIndex { it, i -> println "${i} Key: ${it.key}
正则
[a-z&&[^bc]] 排除法
三种形式
The match operator (==~) 匹配 返回true or false
The find operator (=~) 查找 返回一个java.util.regex.Matcher
The pattern operator (~string) 定义 使用//也是可以
查找的例子
def matcher = winpath =~ /(\w{1}):\\(\w+)\\(\w+)\\(\w+)/
访问结果的时候,注意需要2维数组来进行获取子项
def matcher = winpath =~ /(\w{1}):\\(\w+)\\(\w+)\\(\w+)/
println matcher[0][1] // C
使用~string 可以很方便的声明一个正则表达式
可以通过在Operator运算符 对应的Method 来实现运算符的重载
技巧: 分别调用集合里面对象的指定方法
list.collect { println it.printFullName() }
list*.printFullName()
Elvis运算符 类似Java的三元运算符,不过更方便
def firstName = user.firstName == null ? "unknown" : user.firstName // Java ternary
def firstName2 = user.firstName ?: "unknown" // Groovy Elvis
两个是等效的.... 如果user.firstName为null,那就赋值"unknown"
user?.firstName 其中的?是用来防止该对象是null的
@符号的使用
def todo = new Todo(name: "Jim")
println todo.name
println todo.@name
其中第一个使用get去访问属性,而第二个会绕过get方法
&符号,将方法变成能和CloSure一样传递
c=[1,3,4]
c.each(this.&sa)
def String sa(is)
{
println is;
}
同时这种调用也可以使用在Java的类之上
Writing XML with Groovy MarkupBuilder
def writer = new StringWriter()
def builder = new groovy.xml.MarkupBuilder(writer)
builder.setDoubleQuotes(true)
builder.todos {
todo (id:"1") {
name "Buy Beginning Groovy and Grails"
note "Purchase book from Amazon.com for all co-workers."
}
}
println writer.toString()
JavaScript 不能自闭合,而且要调用在函数定义之下
使用XmlSlurper解析XML
Reading XML with XmlSlurper
def todos = new XmlSlurper().parse('todos.xml')
assert 3 == todos.todo.size()
assert "Buy Beginning Groovy and Grails" == todos.todo[0].name.text()
assert "1" == todos.todo[0]
[email protected]()
.gtpl 模板文件,用于生成指定格式的内容
import groovy.text.SimpleTemplateEngine
读取模板文件
Class.metaClass.getResourceAsText = { resource ->
this.class.getResourceAsStream(resource).getText()
}
def emailTemplate = this.class.getResourceAsText('nightlyReportsEmail.gtpl')
http://www.chinagroovy.org/forum/index.php?topic=72.0 非常详细的用Eclipse开发Grails项目的例子
注意目前看到的还是需要用控制台建立Grails工程,然后进行导入
>grails create-app collab-todo 其中最后一个为工程名字
建立最后需要确定在工程属性的Groovy Project Properties 两个进行打钩
需要时后动设置GRAILS_HOME 在Eclipse里面,和外面设置的无关
> grails run-app 运行程序
编译工程后注意如果在Eclipse开启的情况下修改了环境变量.需要重启下Eclipse
创建一个domain文件
> grails create-domain-class todo
这种类型的文件 类似与JavaBean文件,功能会更多一些 CURT的模型
在Eclipse里面运行Grails编译的时候,注意需要选中项目,再开始运行, grails 在Eclipse里面不需要
domain文件中的 static constraints 用来约束保存前的属性大小限制
static constraints = {
description(maxSize:1000)
}
会同时建立一个Groovy的test文件
该类继承GrailsUnitTestCase,它是继承与Junit,并且封装了部分方便的方法,其中的测试方法,需要用test开头
还是Junit3.x的东西
执行测试的命令
>grails test-app //注意该命令会执行所有的测试,集成和单元,并形成报告
>grails test-app Foo //测试指定的类 其中测试不需要加Tests后缀
grails test-app -unit //也可以选择执行单元测试,或者
grails test-app -integration
-return //不知道是啥意思
创建单元测试
>grails create-unit-test book
创建集成测试
>grails create-integration-test book
可以在test的文件夹下得到详细的测试报告
domain 类中的id和version是不需要显示的去指定的,或声明
GRAILS 下的版本控制,部分文件并不会被上传到SVN上,不过并没有看到介绍怎么直接与SVN整合
构建controller,用于直接和页面交互,也是唯一能够访问Domain的层次
>grails create-controller todo
会自动建立一个TodoController.groovy的类,以及建立一个单元测试类
而且类名会自动格式化,大小写标准
默认建立工程中,数据库会随每次启动自动删除,然后重建
建立ORM映射关系
belongsTo tells GORM to delete the to-do if either the associated user or the category is
deleted
意思是 这个标签表明,这里随主键表对应属性的删除而删除
建立一对多关联,这里会建立一个数组
static hasMany = [todos: Todo]
这个会建立两个数组
static hasMany = [todos: Todo, categories: Category]
工程下的grails-app文件夹里面的view里面提供了页面的布局
先创建简单的模板,便于共享使用
_footer.gsp 使用下划线_开头,并且专门放置在common文件夹内
<g:render template="/common/footer" /> 加入到需要放置的页面中,这里直接放入main.gsp中
其中main.gsp则是其他网页的总体模板
再建立个通用的顶部标签
1:<g:if> and <g:else> tags work together to create “if-then-else” logic.
2:<g:link> tag creates a hypertext link
3:<g:each> 迭代 an iteration tag
在例子中用于显示controller列表
该标签用于放置自定义的内容...其他部分由main.gsp提供
<g:layoutBody />
Grails Tags
Logical Tags //逻辑语句组件
<g:if>
<g:else>
<g:elseif>
Iteration Tags //用于循环的组件
<g:while>
<g:each>
<g:collect>
<g:findAll>
<g:grep>
Assignment Tags //声明对象的组件
<def> (deprecated)
<set>
Linking Tags //超链接组件
<g:link>
<g:createLink>
<g:createLinkTo>
Ajax Tags //Ajax的组件
<g:remoteField>
<g:remoteFunction>
<g:remoteLink>
<g:formRemote>
<g:javascript>
<g:submitToRemote>
Form Tags //表单元素的组件
<g:actionSubmit>
<g:actionSubmitImage
<g:checkBox>
<g:currencySelect>
<g:datePicker>
<g:form>
<g:hiddenField>
<g:localeSelect>
<g:radio>
<g:radioGroup>
<g:select>
<g:textField>
<g:textArea>
<g:timeZoneSelect>
UI Tags //额外的组件
<g:richTextEditor> //使用Fckeditor创建的 用插件形式加载
Render and Layout Tags //布局属性
<g:applyLayout>
<g:encodeAs>
<g:formatDate>
<g:formatNumber>
<g:layoutHead>
<g:layoutBody>
<g:layoutTitle>
<g:meta>
<g:render>
<g:renderErrors>
<g:pageProperty>
<g:paginate>
<g:sortableColumn>
Validation Tags //显示验证与验证结果
<g:eachError>
<g:hasErrors>
<g:message>
<g:fieldValue>