javaer敏捷之路:使用grails 1.1.1有感

 

Scott Davis:

British Sky Broadcasting Group 最近将它的 Web 站点迁移到了 Grails。他们现在每月的点击量达到 1.1 亿次。LinkedIn.com 

在其站点的某些商业部分使用 Grails。Tropicana Juice 在英国有一个 Web 站点,该站点几年来一直在 Grails 上运行。

Grails.org 本身就是用 Grails 编写的,每月支持 70,000 多次下载。

 

美国时间2008年11月11日, SpringSource宣布并购G2One公司(G2One公司拥有Groovy和Grails两大产品)。此次收购后, 

SpringSource现在将会向groovy和Grails开发团队提供全面的技术和解决方案的支持。

 

grails应用的成功案例:

http://grails.org/Success+Stories

 

在grails的门外徘徊了很久,现在是该用它做东西的时候了。

 

[lcl@team ~]$ grails stats

Welcome to Grails 1.1.1 - http://grails.org/

Licensed under Apache Standard License 2.0

Grails home is set to: C:\grails-1.1.1

 

Base Directory: D:\myeclispe-iplatform\iplatform-test-tools

Running script C:\grails-1.1.1\scripts\Stats.groovy

Environment set to development

 

        +----------------------+-------+-------+

        | Name                 | Files |  LOC  |

        +----------------------+-------+-------+

        | Controllers          |     9 |   904 |

        | Domain Classes       |     8 |    95 |

        | Tag Libraries        |     1 |    10 |

        +----------------------+-------+-------+

        | Totals               |    18 |  1009 |

        +----------------------+-------+-------+

 

 

 

有点感慨:

1:敏捷:

东西很小, 但啥都有: permission control/persistence(8 tables)/webservice/ajax/upload

确实够敏捷的:一人日基本就够用了。

 

2:关于GORM:

grails的domain采用“裸对象”(ps:也拥抱配置),把hibenate很薄的封装了一层,让数据库对java程序员完全透明.

观察一下GORM 创建的表结构,居然加入了version控制(多人编辑同一条数据遇到的version问题,Hibernate乐观锁),优化多表关联查询的索引也加好了。

比如如下两个domain class的多对一关系:

 

class Conference{
	static constraints = {
		conference(blank:false, nullable:false, maxSize:3000)
		dateCreated()
	    comments(blank:true, nullable:true)
	  } 
	
	String conference
	Date dateCreated
	String comments
	
	static belongsTo = [type:ConferenceType]
	
}
 

 

 

 

class ConferenceType{
	static constraints = {
	    type(blank:false, nullable:false,maxSize:15)
	    comments(blank:true, nullable:true, maxSize:1000)
	  } 
	
	static mapping = {
		sort "type" 
	}
	
	String type	
	String comments
	
	static hasMany = [conferences:Conference]
	
	String toString(){
		type
	}
}
 

 

 

产生的表结构如下:

 

Conference对应的ddl如下:

 

DROP TABLE IF EXISTS `conference`;
CREATE TABLE `conference` (
  `id` bigint(20) NOT NULL auto_increment,
  `version` bigint(20) NOT NULL default '0',
  `comments` varchar(255) default NULL,
  `date_created` datetime NOT NULL default '0000-00-00 00:00:00',
  `type_id` bigint(20) NOT NULL default '0',
  `conference` longtext NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `FK1D10CF16AD902` (`type_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
 

 

 

ConferenceType对应的ddl如下:

 

DROP TABLE IF EXISTS `conference_type`;
CREATE TABLE `conference_type` (
  `id` bigint(20) NOT NULL auto_increment,
  `version` bigint(20) NOT NULL default '0',
  `comments` longtext,
  `type` varchar(15) NOT NULL default '',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
 

 

 

其中, id,version为所有domain都有的field,grails自动添加

 

2:ajax支持:

 

render mydomain as JSON
 

 

or:

 

render mydomain as XML
 

 

简短之极的语言(分明就是自然语言), 明确的语意。已经把对象变成json/xml并可供前台js使用了。

 

3:自定义标签

一个class搞定:

这是g:textArea的源码:

 

def textArea = {attrs, body ->
        resolveAttributes(attrs)
        attrs.id = attrs.id ? attrs.id : attrs.name
        // Pull out the value to use as content not attrib
        def value = attrs.remove('value')
        if(!value) {
            value = body()
        }
        def escapeHtml = true
        if (attrs.escapeHtml) escapeHtml = Boolean.valueOf(attrs.remove('escapeHtml'))

        out << "<textarea "
        outputAttributes(attrs)
        out << ">" << (escapeHtml ? value.encodeAsHTML() : value) << "</textarea>"
    }
 

 

 

相对于:jsp/struts/struts2/jsf的自定义标签开发,简单到令人发指。

 

目前遇到的grails的一些小问题如下:

一:最敏捷的一个scanffold特性,慎用之

此特性在develop环境下可用。

 

class YourController {
	def scaffold = YourDomain
}
 

但在生产模式下运行:

1:如下环境下不好使, 

tomcat version: version:5.5.27

 

linux version:

 

[lcl@team ~]$ cat /proc/version 
Linux version 2.6.18-53.el5xen ([email protected]) (gcc version 4.1.2 20070626 (Red Hat 4.1.2-14)) #1 SMP Wed Oct 10 16:48:44 EDT 2007
 

 

2:在window xp + tomcat 5.5.17上没问题。

不知道是否跟环境有关。

还是老老实实的用grails create-controller生成controller吧, 其实也还蛮“敏捷”的

二:异步提交标签和actionSubmit混用问题

 

<g:form method="post" > 
....... 
               <div class="buttons"> 
                    <span class="button"><g:actionSubmit class="save" value="Update" /></span>                    
                    <g:submitToRemote action="transfer" update="transfermsg" value="Transfer" onComplete="new Effect.Grow('transfermsg');"/> 
                </div> 
</g:form> 
 

 

单独用g:actionSubmit或g:submitToRemote 提交都没问题 

但是把它们写在一起(如上,同一个form),g:submitToRemote 就不行了,老是调用的save闭包(不调用action="transfer")。

问题有点诡异, 还没深入分析,估计是个bug。

 

三:部署到如上的linux+tomcat环境后,运行一个比较好性能的操作,报如下错误:

java.lang.OutOfMemoryError: PermGen space异常

估计是用grails的默认 grails war,打的package过大,超过31M导致。

解决方法有两个:

1:在Config.groovy 中定义所需的打包jargrails.war.dependencies 和 grails.war.java5.dependencies

具体实现可看官方文档:

http://grails.org/doc/latest/

 

2:比较快速的修复:直接在tomcat的启动脚本增加perm size:

:JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m" 

 

四:domain.list()方法在gsp文件中慎用。

在windows + tomcat5.5下用production模式run没问题

但在如上的linux+ tomcat下, GSP中的domain.list()居然编译不通过。

解决办法:

在controller中, 把domain.list()用[yourList:domain.list()]送到gsp中。

 

不过这点小问题,相对于它的敏捷,基本就忍了。

现在是时候用grails了。

热切的期盼grails社区能热起来。

 

 

 

你可能感兴趣的:(tomcat,linux,敏捷开发,grails,groovy)