First they ignore you
then they ridicule you
then they fight you
then you win
    -- Mahatma Gandhi
Chinese => English     英文 => 中文             
随笔-179  评论-1027  文章-0  trackbacks-0
GORM就是以前我刚学Groovy没多久时想实现的功能,它使开发人员不需要关心数据库方面,也不需要任何配置,只需专心用OO思想设计自己的系统,还有一个好处就是开发时不用备份数据库,因为GORM会自动帮你建表以及约束(但数据库需要你自己建),让我们来看一下用Grails开发是多么简单高效吧!

在Grails0.6+中,配置稍有不同,详见 朝花夕拾——Groovy & Grails

在写域类时,无须添加与业务无关的属性,比如在用Hibernate时,我们需要(不强制)在类中定义id,但用GORM时,id无须自己声明,GORM会帮我们自动添加id和version。GORM通过反射机制获得域类属性信息决定数据库字段类型,所以在定义域类时不要使用def关键字来定义属性,务必明确定义属性类型,比如在下面的域类Article中,用String来定义content(而不是def content),在默认情况下,String映射到数据库中的字段类型是VARCHAR(Date映射到数据库中的字段类型是DATETIME),如果通过类变量contraints定义了String的长度范围,且长度过长,映射到数据库中的字段类型会变为TEXT,十分智能。
eg.
class Article {
  Date dateAdded  // Date 映射到数据库中的字段类型是DATETIME
  String content
  static constraints = {
    content(blank: false, size: 0..65535) // 如果没有定义content的大小范围,它在数据库中类型为VARCHAR最大长度是255,
                                          // 显然不满足我们的需求,这样定义后,数据库中的字段类型会变为TEXT
  }
}

如果将数据源<project name>/grails-app/conf/XXXDataSource中的String dbCreate = "update",Grails会自动帮我们同步内存和数据库中域类对象的状态,这点是很方便的,不需要在每次修改对象后,update了(GORM中的save()相当于Hibernate中的saveOrUpdate()),其好处犹如Java中,new出一个对象,当不再使用此对象时,不需要自行delete一样。在实际开发中您就会体会到了。

下面让我们看一下GORM中的1:1,1:N,N:1,N:N以及继承关系映射:

1,一对一关系:

class Dog {
  String name
  Tail tail //  狗有一条尾巴
}

class Tail {
  float size
  Dog owner  //  尾巴也知道自己属于那只狗
}
现在Dog和Tail的一对一关系是双向的,当然你也可以去掉Tail类中的owner属性或Dog类中的tail属性,使一对一关系变为单向的
级联删除:当Dog对象被删除时,则Dog对象所引用的Tail对象也将被相应删除;同样地,当Tail对象被删除时,Tail对象所引用的Dog对象也将被相应删除。如果你认为Tail被切除后,Dog应该还活着,即Tail对象删除后,Tail对象所应用的Dog对象不应该被删除,那么我们可以通过在Tail类中声明类变量belongsTo来实现,在这个场景中,我们将Tail改为:
class Tail {
  float size
  Dog owner  //  尾巴也知道自己属于那只狗
  static belongsTo = Dog // 注意是static的
}
级联更新/保存:当Dog对象更新/保存,Dog对象所引用的Trail对象也更新/保存;反之亦然。

2,一对多多对一关系:
class Dog {
  String name
  static hasMany = [feet: Foot] // 通过声明类变量hasMany,来定义Dog‘一’这方有多Foot
}

class Foot {
  float size
  Dog owner
  static belongsTo = Dog // 在一对多,多对一关系中,默认‘多’方belongsTo‘一’方
}
关于保存,更新和删除与一对一关系相同,都是级联更新/保存和级联删除,当Dog被删除时,由于Foot belongsTo(属于) Dog,所以Dog对象所引用的所有Foot对象全被删除;而当Foot对象被删除时,Dog对象不会被删除。这是通过类变量belongsTo实现的。

3,多对多关系:
class Teacher {
  String name
  static hasMany = [students: Student]
}

class Student {
  String name
  static hasMany = [teachers: Teacher]
  static belongsTo = Teacher  // 在多对多关系中,至少有一方声明类变量belongsTo
}
更新/保存在多对多关系中,相对一对一,一对多,多对一关系中要特殊点,就是只有‘拥有方’可以级联更新/保存,比如在本例中,由于Student belongsTo Teacher ,所以Teacher是‘拥有方’,Teacher的更新/保存将引起Teacher对象所引用的所有Student对象的更新/保存。
删除也有点特殊,‘拥有方’被删除后,它所引用的对象不会被删除,你必须自己删除它们,否则它们将成为‘孤儿’

4,继承关系:
class Base {...}
class Derived extends Base {...}
只要定义类,无需任何配置,够简单吧。

用Grails开发就是这么简单快捷,域类定义好了之后,剩下的事情,比如建表,约束等,Grails全帮您自动搞定,很省心!Grails官方网站上有很多文档供参考,对GORM的进一步学习,您可以看一下GORM

附:Groovy轻松入门--Grails实战基础篇

posted on 2007-04-05 14:27 山风小子 阅读(3535) 评论(16)  编辑  收藏 所属分类: Groovy & Grails

评论:
# re: Groovy轻松入门--Grails实战之GORM篇 2007-04-05 21:24 | 海边沫沫
不错啊
static hasmany=...这种写法比Hibernate的Annotation还要方便  回复  更多评论
  
# re: Groovy轻松入门--Grails实战之GORM篇 2007-04-06 15:45 | 山风小子
@海边沫沫
嗯,是的,所以用Grails开发时很舒心 :)  回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日) 2007-04-11 10:59 | 花生米
写的不错,支持一下!希望看到更多好的文章  回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日) 2007-04-11 14:15 | 山风小子
@花生米
谢谢 :)  回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日) 2007-05-09 13:38 | 鱼肠剑
希望多写一点.学习中!

支持!!!  回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日) 2007-05-09 15:00 | 山风小子
@鱼肠剑
嗯,我会的 :)  回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日) 2007-05-27 12:12 | Rondy.F
@山风
请教一个问题:
在使用GORM时我发现了一个问题,比如我有一外domain对象News,我在NewsController中定义了一个action,它功能是删除一个News实例,然后返回数据库列表:
def news = News.get(params.id)
news.delete()
def list = News.list(...)
但是我发现它的执行顺序是:get,list,delete,这是我通过打出的SQL语句断定的,但我把上面三句放在一个事务里的时候,顺序是正常的:get,delete,list,不知道这是什么原因????????????
我的邮箱是:fuxueliang@gmail.com(*_*)
  回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日)[未登录] 2007-09-27 13:44 | cc
请问 control的转向页面在那个文件里面配置啊 ,我找了 好久没找到
我做得例子进去的页面有,下面这2个连接,
LoginController
UserController
奇怪的是UserController 是好的都可以用,但是LoginController 点击后显示有异常
HTTP ERROR: 404
/WEB-INF/grails-app/views/login/index.jsp
RequestURI=/demo/login/
Powered by Jetty://
找不到 哪来的jsp啊谢谢
我的邮箱:gcc1984629@163.com
qq:281663415  回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日) 2007-09-27 19:59 | 山风小子
这是因为UserController有相应的domain class——User,一般我们会grails generate-all User一下,这样所有的代码都生成好了,其中包括gsp文件。
而对于LoginController来说,它应该没有相应的domain class,因此你不能用generate-all命令来生成‘所有’的代码,只能自己手动创建,我想你应该没为LoginController手动创建过任何gsp文件吧,比如list.gsp。

我在《 Groovy轻松入门——Grails实战基础篇》写那个LoginController是为了说明‘不是非得存在domain class才能有controller的’,其实你只要先创建用grails create-domain-class创建User这个domain class,然后用grails generate-all User来生成所有关于User domain class的代码即可 :)

最后我想说明一点,通常情况下用Grails开发无需任何配置,请仔细研究一下Grails自动帮你生成的UserController.groovy,你就知道如何跳转页面了 :)

希望我的回答对你有所帮助。

如果还有什么问题,请到我们群里问以得到及时的回答 :)  回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日) 2007-09-28 14:03 | 穆先生
接触Grails第1天,看到这里,例子也做了,测试成功,但是还是感觉模模糊糊  回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日) 2008-02-19 17:01 | 木东
GORM确实不错,不过看完我有一个疑问。
他的关联对象的抓取策略是什么?
不然性能的问题怎么解决啊   回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日) 2008-02-19 17:30 | 木东
刚才查了一下grail的文档,看来我有点多虑了,谢谢楼主,教程写的不错

The default fetch strategy used by Grails is "lazy", which means that the the collection will be lazily initialized. This can lead to the n+1 problem if you are not careful.

If you need "eager" fetching you can use the ORM DSL or specify eager fetching as part of a query   回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日) 2008-03-04 11:10 | henry
ORM这块仍然比Rails复杂很多  回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日) 2008-05-29 09:27 | ano
Dog owner // 尾巴也知道自己属于那只狗
static belongsTo = Dog // 注意是static的


要是grails这种写法要能设计成
static belongsTo = [owner: DOG]

应该更符合DRY

  回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日) 2008-05-29 12:04 | ano
不好意思,文档上就有这种写法,不过不知这两种写法有什么区别
  回复  更多评论
  
# re: Groovy轻松入门——Grails实战之GORM篇(更新于2007年4月8日)[未登录] 2008-09-01 10:35 | sword
问个问题,如果一个表org自己存在一对多的关系,应该怎么写啊?
class org {
int id
int parentId
static hasMany = [orgs:org]
}
这样写就可以了嘛 ?  回复  更多评论
  


标题  
姓名  
主页
验证码 *  
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-09-26 21:06 编辑过