grails学习笔记

配置篇

  • 在config.groovy文件中有名为layer1.prop1的参数。请问,在Controller中如何访问它?在Service中呢?

    访问方式一样,可采用以下任意一种方法:

    1grailsApplication.config.layer1.prop1
    2//或者
    3ConfigurationHolder.config.layer1.prop1
  • 如何编辑Grails应用的web.xml文件?

    先使用命令:“grails install-template”安装Template,之后在AppHome/src/templates/war/目录下找到web.xml,修改之。

  • 请解释一下外部配置。它有什么好处?

    grails-app/conf目录下的默认配置文件Config.groovy在大多数情况下就够用了,但是有可能你希望在应用之外维护配置信 息。比如,数据库链接信息,以避免配置修改时需要重新打包WAR。为了支持这些个部署场景,Grails提供了外部部署。你可以在 Config.groovy文件中指定外部配置文件的位置,比如:

    1 grails.config.locations = [ "classpath:${appName}-config.properties",
    2 "classpath:${appName}-config.groovy",
    3 "file:${userHome}/.grails/${appName}-config.properties",
    4 "file:${userHome}/.grails/${appName}-config.groovy"]
  • 请解释一下Config.groovy和BuildConfig.groovy文件的区别。

    Config.groovy是主配置文件,BuildConfig.groovy则侧重构建环境。

  • 请解释一下Bootstrap.groovy的作用?

    在Bootstrap.groovy中,可以定义应用程序启动和停止时执行的代码。

工具/Shell篇

  • 描述一下Grails的console、shell和交互模式(interactive modes)的区别?
    • console:在初始化的Grails环境中运行的Groovy图形控制台,启动方式:“grails console”;
    • shell:在初始化的Grails环境中运行的Groovy Shell,启动方式:“grails shell”;
    • 交 互模式:以交互方式启动Grails CLI,类似在命令行下执行Grails命令,不同之处在于该模式只启动一次JVM,节省了每次执行Grails脚本时启动JVM的时间,同时它还使用 JVM的JIT编译器优化Grails脚本,有效提升了需要反复执行的脚本(如单元测试)的执行速度。启动方式:“grails interactive”;
  • 在Grails console中如何获得Spring bean?

    Grails Console有一个绑定变量ctx,它指向ApplicationContext对象,使用如下代码即可获得Spring Bean:

    1ctx.getBean(beanId)

    详情可参见本站的《如何在Grails Console中调用GetBean》

  • 在Grails console下有哪些注意事项?

    【没弄明白原题的意思,故参考了Tomás Lin的答案】BootStrap.groovy中的内容不会执行;部分工程文件的改动会使Console重启,如Controller的变动不会引起重 启,而Domain Class的文件则会。同时,Tomás的说重启时会造成原来输入的代码丢失,实际情况似乎不是这样,重启之后,原来输入的代码会被加载。但为了保险起 见,如果代码太长了,最好还是保存在外部。

  • 当执行“grails bug-report”,会发生什么事情?

    bug-report用于报告Bug,它仅将应用的源文件打包(不包括Jar文件、静态资源等)生成带有时戳的ZIP文件,它向Grails JIRA报告问题非常有用。

  • Grails中自带的环境有哪些?

    Grails中自带的环境有:开发环境:development;产品环境:Production,测试环境:Test。

    同时,Grails还允许自定义环境,在运行时则需要通过grails.env参数来告知当前环境。详情请参见本站Grails 1.2参考文档速读(2):配置基础和环境

  • 如何改变应用程序使用的服务器端口?

    grails run-app -Dserver.port=port number或者使用grails.server.port配置。

  • 请讲述run-app和run-war的区别?

    run-war:将当前的应用程序打包成WAR,并在Jetty容器的8080端口运行应用。

    run-app:在Jetty容器的8080端口运行应用。

  • Grails中,如何创建自定义脚本?

    使用create-script命令创建,比如:

    1//创建scripts/ExecuteReport.groovy
    2grails create-script execute-report
  • 什么是_Events.groovy?它是干什么用的?

    _Events.groovy中可定义事件处理函数,它可以存放在插件的scripts目录下,或者用户目录的.grails/scripts/下。当事件发生时,会调用所有的_Events.groovy文件。详情请参见本站Grails 1.2参考文档速读(5):第4章

  • 假如,我的应用程序处于编译循环中,我猜是因为一个类名跟文件名不一致造成的。我该怎么进行调试?

    使用verboseCompile:“grails compile -verboseCompile”,或者将grails.project.compile.verbose设置为true。

GORM / 数据库

  • 请解释一下dbCreate参数的不同值的区别?

    可用值有create-drop、create、update和validate:

    • create:启动时重新建表;
    • create-drop:启动时重新建表,停止时,drop所有表;
    • update:启动时更新当前的schema,相当于alter table。
    • validate:检查当前的Schema是否跟Domain匹配,不会对数据库做任何修改。
    • null:什么也不干
  • 什么是动态查找器?

    动态查找器是根据Domain Class属性生成的查找方法,这些方法由前缀为findBy和findAllBy的构成,构造规则(以findBy为 例):DomainClass.findBy([Property][Comparator] [Boolean Operator])?[Property][Comparator]。详情可参见本站Grails 1.2参考文档速读(8):GORM中的查询

  • 动态查找器最多有几个参数?

    3,其中2个是属性,另一个是操作符。比如:

    Book.findBy([Property][Comparator][Boolean Operator])
  • 衣柜里有许多鞋。我想保持衣柜对象中鞋子的插入顺序。该怎么办?

    将鞋子属性设置成List,比如:

    1 class Closet {
    2 List shoes
    3 static hasMany = [shoes:Shoe]
    4}
  • 请解释一下GORM的joinTable。

    joinTable,顾名思义,指的是“关联表”,如多对多中用来保存关系的“中间表”。但是关联表不是多对多的专利,在一对多时,若只有 hasMany,而没有belongsTo,同样也会GORM创建关联表。因为此时表示,多端不一定有一端对应的类,即多端的一端可能为null。这句话 有点绕口不是吗?简单点,就是外键可能为null。这对于关系数据库来讲可不是一个好的实践。所以对于只有hasMany的Domain Class来讲,在它们之间创建关联表最合适。可视为退化的“多对多”。

    关于关系的详情,请参见Grails 1.2参考文档速读(6):GORM基础和关系建模。这部分内容可是本站独家,参考文档上是没有的哦!

  • 请解释一下GORM的lock(),什么情况下会使用它?

    想获得悲观锁时,详情请参见Grails 1.2参考文档速读(7):GORM建模的其余事项及持久化基础

  • GORM中read()和get()的区别是什么?

    都是根据指定ID获得Domain Class。但read的目的是读出来的对象用于只读,而get则没有这个限制。

  • Domain对象中的removeFrom()是什么意思?

    跟addTo方法相对,在多端的关联中移除实例。

  • 什么是命名查询?在哪里定义它们?

    即可重用的Criteria,使用namedQueries定义。

  • 动态查找器、HQL和Criteria的不同点是什么?

    动态查找器是根据Domain Class的属性生成的查找方法,诸如findBy**、findAllBy**。最多应用于2个属性;返回结果集是以Domain Class为单位的,无法返回任意结果集,如只包含部分Domain Class的属性的结果集;无法用于任意类之间的关联,关联的类之间需存在关系。

    HQL,类似SQL,通过executeQuery使用。可以返回任意的结果集,可以实现任意类之间的关联。

    Criteria,即Hibernate的Criteria在GORM中的DSL,通过createCriteria或withCriteria方法使用。无属性个数限制,可以实现复杂的关系操作。

  • Grails中的projection什么意思?

    即关系代数中的投影概念,可用于自定义返回的结果,如select中指定返回的列,就是一种投影操作。在HQL和Criteria中均可使用。

  • Grails中如何直接运行SQL?
    1 new Sql(dataSource).execute sqlstr
  • Gorm提供了两个自动时间戳的变量,是什么?

    lastUpdated和dateCreated

  • 解释一下GORM的事件,并举2例。

    可视为GORM的触发器,其作用跟数据库的触发器类似,通过在Domain Class中定义闭包实现,在Domain对象保存之前或之后执行。例如:beforeInsert、afterUpdate。

  • Domain Class中有一个属性,不想持久化。如何保证这个属性不会在数据库中生成一个字段?

    在Domain Class中使用“transients”,例如:

    1 class User {
    2 String address
    3 ......
    4 static transients = ['address']
    5}
  • 我想在Grails应用中包含一个Hbernate的HBM文件,该怎么做?

    在grails-app/conf/hibernate目录下,创建hibernate.cfg.xml,并把HBM文件也防置在这个目录下。

  • 如何查看Grails的内置HSQL数据库?

    可以将代码:

    1org.hsqldb.util.DatabaseManager.main()

    在应用内的任何地方或者Grails Console中,运行上述代码会启动HSQLDB的Console连接界面。在这个界面中,将URL属性值jdbc:hsqldb:mem:* 中的“*”更换成devDB或者你自己定义的数据库名,如“jdbc:hsqldb:mem:devDB”,之后单击OK,就能够看到该数据库中的表结构 了。

    或者直接使用:

    1 org.hsqldb.util.DatabaseManagerSwing.main( ['--url', 'jdbc:hsqldb:mem:devDB'] as String[] )
  • Grails如何使用多个数据库?

    使用Datasources插件

  • 如何根据数据库生成Domain Classe?

    可以使用Grails逆向工程插件实现,具体使用可参见本站《使用Grails进行数据库逆向工程》

    或者使用GRAG

关于Hibernate的内容不可不读,尤其是《Java Persistence with Hibernate》这本书。

验证篇

  • Grails中的约束是什么意思?请给出3个示例。

    跟数据库中的约束类似,在保存前,Grails会先使用它来验证Domain Class的各个属性,若不能通过,则无法保存或修改,例如:

    1 static constraints = {
    2 login(size:5..15,blank:false,unique:true)
    3 password(size:5..15,blank:false)
    4 email(email:true,blank:false)
    5 age(min:new Date(),nullable:false)
    6}

    详情可参考本站的《Grails 1.2参考文档速读(15):验证》。

  • 请给出两个影响视图脚手架显示的约束。

    display:如果true(缺省值),属性将显示;
    editable:如果false,相关表单字段只读。

  • 请给出两个影响数据库生成的约束。

    maxSize(minSize):限制属性值大小,对应列大小;
    size:限定属性值大小范围。

  • 如果验证失败,我希望Domain对象抛出异常,该怎么做?

    Grails提供了配置项:grails.gorm.failOnError,如果设置成true,验证失败时,save()就会抛出grails.validation.ValidationException异常。

  • 什么是Grails命令对象?在验证中如何使用?

    对于不想直接暴露Domain Class的场合,可以使用Command Object来代替。Grails的Command Object跟Spring MVC中的没什么区别,是一个View Object。

    01 class LoginController {
    02 def login = { LoginCommand cmd -<
    03 if(cmd.hasErrors()) {
    04 redirect(action:'loginForm')
    05 }else {
    06 // do something else
    07 }
    08 }
    09}
    10 class LoginCommand {
    11 String username
    12 String password
    13 static constraints = {
    14 username(blank:false, minSize:6)
    15 2011-2-9·password(blank:false, minSize:6)
    16 }
    17}

    详情可参考本站的《Grails 1.2参考文档速读(10):Controller》。

  • validate()和save()的区别?

    validate用于验证;save()用于保存。在进行实际的保存前,save会调用validate,失败则不保存;反之,保存。

  • 有一个类存于src/groovy下,我想为其加入验证,该怎么做?

    方法1:

    1. 将类用@Validateable注解
    2. 在类中定义constraints静态属性
      01 import org.codehaus.groovy.grails.validation.Validateable
      02@Validateable
      03 class User {
      04...
      05 static constraints = {
      06 login(size:5..15, blank:false, unique:true)
      07 password(size:5..15, blank:false)
      08 email(email:true, blank:false)
      09 age(min:18, nullable:false)
      10 }
      11}
    3. 在Config.groovy中定义要查找@Validateable的包名:grails.validateable.packages
      1 grails.validateable.packages = ['com.mycompany.dto', 'com.mycompany.util']

    方法2:

    1. 在类中定义constraints静态属性
      1 class User {
      2...
      3 static constraints = {
      4 login(size:5..15, blank:false, unique:true)
      5 password(size:5..15, blank:false)
      6 email(email:true, blank:false)
      7 age(min:18, nullable:false)
      8 }
      9}
    2. 在Config.groovy中注册类名: grails.validateable.classes
      1grails.validateable.classes = [com.mycompany.myapp.User , com.mycompany.dto.Account]

      详情可参考《Grails 1.2参考文档速读(15):验证

控制器篇

  • 请解释一下Grails中,Controller与Service的区别。
    • Controller属于Web层的范畴,主要作用是为View的显示做好准备工作,或是针对请求准备好响应的数据。每次请求创建新实例
    • 服务层的作用是封装复杂业务逻辑,尤其是这种逻辑涉及到多个Domain Class的时候。
  • 什么是flash对象?在Grails应用中,flash对象有替代用法么?

    Flash对象是在会话中临时保存的map,可用于下一次请求。在下一次请求结束后,该对象会自动清除。
    可以使用chain代替flash,用法:

    1 chain(action:"a", model:[one:1],params:[p:"v"])
  • 表单中有6个朋友的名字,均使用名为‘friendName’的text输入框。在Controller中如何获得它们的list?
    1params.list(friendName)
  • 我想在Controller的Action中给一些请求返回XML文件,而另一些请求返回一个HTML文件。该如何做?

    首先在grails-app/conf/Config.groovy中,使用grails.mime.types告诉Grails需要支持哪些HTTP请求类型,这个属性缺省已经配置:

    01grails.mime.types = [
    02 html: ['text/html','application/xhtml+xml'],
    03 xml: ['text/xml', 'application/xml'],
    04 text: 'text/plain',
    05 js: 'text/javascript',
    06 rss: 'application/rss+xml',
    07 atom: 'application/atom+xml',
    08 css: 'text/css',
    09 csv: 'text/csv',
    10 all: '*/*',
    11 json: ['application/json','text/json'],
    12 form: 'application/x-www-form-urlencoded',
    13 multipartForm: 'multipart/form-data'
    14]

    在Controller中可根据HTTP请求的类型,确定返回的内容:

    01 import grails.converters.*
    02
    03 class BookController {
    04 def books def list = {
    05 this.books = Book.list()
    06 withFormat {
    07 html bookList:books
    08 js { render "alert('hello')" }
    09 xml { render books as XML }
    10 }
    11 }
    12}
  • 我想把Domain对象转换成XML。怎么样能够保证Domain对象的所有子项都完整的转换到了XML中?

    可以使用grails.converters.XML或者grails.converters.deep.XML。

  • Grails中的redirect()使用的是哪种重定向?如何改变?

    缺省情况下,redirect()方法是用的是302重定向。但是如果要修改可使用如下方法:

    1 redirect(action: "list")
    2
    3//变更为
    4 response.setStatus(301)
    5 response.setHeader("Location", "list")
  • 什么是Filter?

    请记住:Grails Filter != JEE Filter。Grails实际上就是grails-app/conf下以Filters结尾的Groovy类。Grails的Filter同样有 Filter链的概念,它本质上是由多个filter定义组成,定义顺序=执行顺序。Filter应用的范围可以是针对Controller和 Action。

视图篇

  • 布局、视图和模板的区别是什么?
    • 布局确定页面结构,用于装饰视图,布局文件位于grails-app/views/layouts。
    • 视图用于前端展现,给用户提供应用程序的使用界面,视图文件位于grails-app/views中。
    • template是可重用的页面片断。名字以下划线开始,如“_bookTemplate.gsp”,其定位规则同View。
  • 什么是命名URL Mapping?它跟一般的URL mappings有什么不同?

    命名URL Mapping即有名字的URL Mapping。在使用该映射时,需要指定其名字。而一般的URL mappings在使用时不需指定名称即可自动匹配。

    1//定义方式如下
    2 static mappings = {
    3 name <mapping name>: <url pattern> {
    4 // ......
    5 }
    6}
    7//用法如下:
    8 <g:link mapping="mapping name">List People</g:link>
  • 在Grails中如何使用不同的布局?

    在grails-app/views/layouts下创建布局mylayout.gsp,在需要使用的GSP中调用:

    1 <meta name="layout" content="mylayout"></meta>

    其中mylayout就是mylayout.gsp的文件名。

  • pageProperty标签是干什么用的?如何使用?

    在布局文件中使用,用于输出被装饰页面的某个属性,等同于SiteMesh的<decorator:getProperty/>标签。

  • 请解释一下<g:form>与<g:formRemote>的区别。

    <g:form>:创建一个用于提交的form。
    <g:formRemote>:触发一个Ajax调用。

  • 我创建了自己的标签库,想在form中以如下方式:<mylib: * >使用,该怎么做?

    为你的标签库指定一个名为“mylib”的命名空间:

    1 class SimpleTagLib {
    2 static namespace = "mylib"
    3
    4 def example = { attrs ->...... } }
    5//用法:
    6 <mylib:example name="..." />
  • 在<g:form>中,希望单击按钮时进行一个Ajax的调用,该怎么做?
    1 <g:submitToRemote/>
  • 请解释一下remoteLink标签中的update属性。

    update:成功和失败时,显示结果的<div>的id。update还可以只指定一个:update="message",其值是<div>的id。例如:

    1 <div id="message"></div>
    2 <div id="error"></div>
    3 <g:remoteLink action="delete" id="1"
    4 update="[success:'message',failure:'error']">
    5 Delete Book
    6 </g:remoteLink>
  • <tmpl:>是做什么用的?

    Template由于使用频繁,因此Grails给它建立单独的名字空间:tmpl。如:

    1 <g:render template="bookTemplate" model="[book:myBook]" />
    2//可简写成:
    3 <tmpl:bookTemplate book="${myBook}" />
    4
  • 为Ajax调用指定Javascript库的两种方式是什么?
    1 <g:javascript src="yui***.js" />
    2 <g:javascript library="yui" />
  • 请解释一下<g:include>标签。

    在当前页面中包含另一个Controller/Action的响应或者视图。

脚手架篇

  • 能解释一下Grails中的静态脚手架和动态脚手架的区别么?

    在Controller不含CRUD action,而是使用scaffold属性,所有的CRUD接口将在运行期间动态生成,这就是动态脚手架。
    而静态脚手架则是通过generate-controller或者generate-all命令生成Controller,在Controller中有CRUD action。

  • 如何修改Grails提供的缺省脚手架?

    运行:grails install-templates,在grails-app\src\templates\scaffolding目录下是缺省的脚手架,可以自行修改。

  • 什么是renderEditor.template文件?它干什么用的?

    该文件位于grails-app\src\templates\scaffolding目录下。它是同目录下的create.gsp和edit.gsp文件使用的模板文件,该模板根据不同的属性类型返回不同的grails的formtaglib

  • generate-views和generate-all的区别是什么?

    generate-views用于生成Domain Class的视图;
    generate-all用于生成Domain Class的控制器及视图。

  • 如果我想重新生成所有Domain Class的脚手架,该运行哪个命令?
    1grails generate-all *

服务

  • 有两个服务,服务A中有“static transactional = true”,而服务B中没有,这两个服务有什么区别?

    服务A具有事务性,而服务B不具有。

  • 什么是服务的范围?能提供三中不同的服务范围么?

    用过Spring的读者应该对Spring的scope不会陌生,它决定了bean的创建方式和生命周期,跟并发性不无联系。一般状况,服务的缺省scope是Singleton,scope的值包括:

    • prototype:新实例/注入时
    • request:新实例/request
    • flash:新实例/flash
    • flow:新实例/flow
    • conversation:新实例/conversation
    • session:新实例/session
    • singleton(缺省):自始至终一个实例

    改变缺省的Scope(在服务定义中)增加:static scope = "以上之一"。

  • 在Domain Class中如何注入一个服务?Servlet中如何做呢?

    用法:

    1 def bookService //对应BookService

    在Servlet中,可以通过Spring ApplicationContext的getBean方法获取到Service的实例:

    1//以BookService为例
    2BookService sc= (BookService)ApplicationHolder.getApplication()
    3 .getMainContext().getBean(bookService);
  • 我想在服务中使用Grails的createLink方法,该如何做?

    在Service中可以这样做:

    1 def g = new org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib()
    2
    3//获得绝对link为:http://localhost:8080/jqac/role/index
    4 def absoluteLink = g.createLink(controller: 'role', action: 'index',absolute:"true")
    5
    6//获得相对link为:/jqac/role/index
    7 def relativeLink = g.createLink(controller: 'role', action: 'index')

测试

  • 在单元测试中如何添加配置项?
    1 import org.codehaus.groovy.grails.commons.ConfigurationHolder
    2//添加配置项
    3 mockConfig '''
    4 you.test.configitem = "groovyq"
    5 '''
    6//获取配置项
    7ConfigurationHolder.config.you.test.configitem
  • 请解释一下单元测试中mockDomain()的作用。还有其他做法可以替代这个方法么?

    在单元测试时,可以使用这个方法对Domain Class 进行Mock,用于模拟Domain Class。替代用法是使用mockFor。

  • Grails支持4中测试类型,请简单描述一下。
    • unit:单元测试类型
    • integration:集成测试类型
    • spock:这是Spock插件添加的测试类型,可用于unit、integration和functional测试阶段。
    • 自定义:可自定义测试类型,具体参见Custom Grails Test Types/Phases
  • 我想在测试中模拟一个发送给Controller的XML文件,该怎么做?
    1 controller.request.contentType = 'text/xml'
    2 controller.request.contents = '''
    3 <?xml version="1.0" encoding="ISO-8859-1"?>
    4 <book>
    5 <title>The Stand</title>
    6 ...
    7 </book>
    8 '''.getBytes()
  • applyTemplate方法是干什么用的?在测试中使用它的目的是什么?

    该方法可以直接获得标签库的结果,可对页面元素进行测试,通常用于集成测试。

  • 什么是页面对象?哪个Grails插件提供了页面对象的支持?

    页面对象表示应用中特定的页面,其中定义了方法和属性,以便于测试与页面进行交互。

    Selenium RC插件提供了页面对象的支持。关于它的使用,请参见本站的用Selenium RC插件测试远程应用

  • 我想将测试结果显示在Console中,该怎么做?

    缺省况下,Grails不会在控制台上输出测试类中的log.info/print/println,如果希望显示,可以使用-echoOut和-echoErr参数,用法如下:

    1grails test-app -echoOut -echoErr
  • 假如,我想在测试中执行one single method,该怎么做?
    1//测试SimpleControllerTest中的testLogin方法
    2grails test-app SimpleController.testLogin

    『编者注』:one single method这里提供的用法有误。

关于Grails的测试细节,亦可参见Grails 1.2参考文档速读(17):测试

插件

  • 请解释一下Grails应用跟Grails插件的区别。

    Plugin是Grails的主要扩展点,其工程跟普通Grails工程并无区别,只是多了一个描述文件。描述文件位于位于工程根目录,是以 GrailsPlugin结尾的Groovy文件。同时,工程中缺省没有URL Mappings,因此Controller无法马上工作,如果需要则必须手工添加该文件。

  • 什么是in-place插件?哪里定义它?

    in-place插件就是无需更新,直接生效的插件。在主工程的BuildConfig.groovy中添加:

    1 grails.plugin.location."my-plugin" = "../my-plugin"

    亦可参见本站的《如何把应用划分成插件?》

  • 如何获得Grails中所有插件的列表?

    使用命令:grails list-plugin

  • 我想用插件来维护数据库结构的一个记录。我应该考虑哪些插件?你会选择哪个?

    可以考虑LiquiBase或者Autobase,推荐使用LiquiBase,这是数据库迁移的官方插件。

  • 我想用插件来帮我管理CSS和javascript文件。你的选择是什么?

    可以使用resources插件。

  • 我想通过插件来设置可运行的浏览器测试,你的建议是什么?

    建议使用Geb

  • 我已经创建了世上最酷的的插件,请问该怎么将这个插件提交到Grails资源库中?

    使用命令:grails realse-plugin

  • 如何提交一个位于Github上的插件,这个插件在Grails插件SVN中没有拷贝。

    使用zipOnly参数,仅在SVN中保存插件的zip文件以及元数据(plugin.xml):

    grails release-plugin -zipOnly 
  • 你如何测试Grails应用的代码质量以及覆盖率?

    使用GMetrics对代码质量进行分析,使用Clover Code Coverage for GrailsCobertura分析代码覆盖率。

  • 你熟悉的哪些RIA技术在Grails中可以使用?

    Flex插件ULC插件ZK插件

1. 简介 2. 起步 2.1 下载并安装Grails 2.2 创建一个Grails应用 2.3 Hello World示例 2.4 使用IDE 2.5 规约配置 2.6 运行Grails应用 2.7 测试Grails应用 2.8 部署Grails应用 2.9 所支持的Java EE容器 2.10 创建工件 2.11 生成Grails应用 3. 配置 3.1 基本配置 3.1.1 内置选项 3.1.2 日志 3.2 环境 3.3 数据源 3.3.1 数据源和环境 3.3.2 JNDI数据源 3.3.3 自动数据库移植 3.4 外部配置 3.5 定义版本 4. 命令行 4.1 创建Gant脚本 4.2 可复用的Grails脚本 4.3 脚本中的事件 4.4 Ant和Maven 5. 对象关系映射(GORM) 5.1 快速指南 5.1.1 基本的CRUD 5.2 在GORM中进行领域建模 5.2.1 GORM中的关联 5.2.1.1 一对一 5.2.1.2 一对多 5.2.1.3 多对多 5.2.2 GORM的组合 5.2.3 GORM的继承 5.2.4 集合、列表和映射 5.3 持久化基础 5.3.1 保存和更新 5.3.2 删除对象 5.3.3 级联更新和删除 5.3.4 立即加载和延迟加载 5.3.4 悲观锁和乐观锁 5.4 GORM查询 5.4.1 动态查找器 5.4.2 条件查询 5.4.3 Hibernate查询语言 5.5 高级GORM特性 5.5.1 事件和自动实现时间戳 5.5.2 自定义ORM映射 5.5.2.1 表名和列名 5.5.2.2 缓存策略 5.5.2.3 继承策略 5.5.2.4 自定义数据库标识符 5.5.2.5 复合主键 5.5.2.6 数据库索引 5.5.2.7 乐观锁和版本定义 5.5.2.8 立即加载和延迟加载 5.6 事务编程 5.7 GORM和约束 6. Web层 6.1 控制器 6.1.1 理解控制器和操作 6.1.2 控制器和作用域 6.1.3 模型和视图 6.1.4 重定向和链 6.1.5 控制器拦截器 6.1.6 数据绑定 6.1.7 XML和JSON响应 6.1.8 上传文件 6.1.9 命令对象 6.2 Groovy Server Pages 6.2.1 GSP基础 6.2.1.1 变量和作用域 6.2.1.2 逻辑和迭代 6.2.1.3 页面指令 6.2.1.4 表达式 6.2.2 GSP标签 6.2.2.1 变量和作用域 6.2.2.2 逻辑和迭代 6.2.2.3 搜索和过滤 6.2.2.4 链接和资源 6.2.2.5 表单和字段 6.2.2.6 标签作为方法调用 6.2.3 视图和模板 6.2.4 使用Sitemesh布局 6.3 标签库 6.3.1 简单标签 6.3.2 逻辑标签 6.3.3 迭代标签 6.3.4 标签命名空间 6.4 URL映射 6.4.1 映射到控制器和操作 6.4.2 嵌入式变量 6.4.3 映射到视图 6.4.4 映射到响应代码 6.4.5 映射到HTTP方法 6.4.6 映射通配符 6.4.7 自动重写链接 6.4.8 应用约束 6.5 Web Flow 6.5.1 开始和结束状态 6.5.2 操作状态和视图状态 6.5.3 流执行事件 6.5.4 流的作用域 6.5.5 数据绑定和验证 6.5.6 子流程和会话 6.6 过滤器 6.6.1 应用过滤器 6.6.2 过滤器的类型 6.6.3 过滤器的功能 6.7 Ajax 6.7.1 用Prototype实现Ajax 6.7.1.1 异步链接 6.7.1.2 更新内容 6.7.1.3 异步表单提交 6.7.1.4 Ajax事件 6.7.2 用Dojo实现Ajax 6.7.3 用GWT实现Ajax 6.7.4 服务端的Ajax 6.8 内容协商 7. 验证 7.1 声明约束 7.2 验证约束 7.3 客户端验证 7.4 验证和国际化 8. 服务层 8.1 声明式事务 8.2 服务的作用域 8.3 依赖注入和服务 8.4 使用Java的服务 9. 测试 9.1 单元测试 9.2 集成测试 9.3 功能测试 10. 国际化 10.1 理解信息绑定 10.2 改变Locales 10.3 读取信息 11. 安全 11.1 预防攻击 11.2 字符串的编码和解码 11.3 身份验证 11.4 关于安全的插件 11.4.1 Acegi 11.4.2 JSecurity 12 插件 12.1 创建和安装插件 12.2 理解插件的结构 12.3 提供基础的工件 12.4 评估规约 12.5 参与构建事件 12.6 参与运行时配置 12.7 运行时添加动态方法 12.8 参与自动重载 12.9 理解插件加载的顺序 13. Web服务 13.1 REST 13.2 SOAP 13.3 RSS和Atom 14. Grails和Spring 14.1 Grails的支柱 14.2 配置其他Bean 14.3 通过Beans DSL运行Spring 14.4 配置属性占位 14.5 配置属性重载 15. Grails和Hibernate 15.1 通过Hibernate注释进行映射 15.2 深入了解 16. 脚手架
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值