文档章节

Groovy&Grails-代码剪辑-对象关系

寡鸡蛋
 寡鸡蛋
发布于 2013/10/03 00:28
字数 1183
阅读 52
收藏 0
点赞 0
评论 0

One To One

一张脸上只有一个鼻子。

<!-- lang: groovy -->
class Face {
    Nose nose
}

class Nose {
}

这是一个简单的单向关联,从face对象可以查到这个nose的信息,从nose就没办法了。如果要达到这个效果,需要把这个关联修改成双向的,代码如下:

<!-- lang: groovy -->
class Face {
    Nose nose
}

class Nose {
    Face face
}

这样双向查询就没有问题了,但是不能级联更新,如果需要更新需要一个对象一个对象的增加。如果我们在实例化Face的时候同时把Nose也增加一条信息,则需要增加一个级联更新属性,代码如下:

<!-- lang: groovy -->
class Face {
    Nose nose
}

class Nose {
    static belongsTo = [face:Face]
}

在这里,我们使用belongsTo 表示Nose "属于" Face。其结果就是我们创建并保存它时,数据库可以_级联_更新/插入 Nose,实例化代码如下:

<!-- lang:groovy -->
new Face(nose:new Nose()).save()

上面这段代码会将fase和nose都保存到数据库,需要注意的是反向操作是不行的,错误代码如下:

<!-- lang:groovy -->
new Nose(face:new Face()).save() // 这样会报错

belongsTo 的另一个重要作用是,如果你删除了一个Face 实例,那么相关的Nose也会被删除,操作代码如下:

<!-- lang:groovy -->
def f = Face.get(1)
f.delete() // Face和Nose实例都会被删除

如果没有 belongsTo 的话,将不会级联删除,你会得到一个外键约束的错误,除非你手工去删除Nose。

<!-- lang:groovy -->
// 如果没有belongsTo会报错,因为有约束
def f = Face.get(1)
f.delete()

// 所以没有belongsTo时需要手工删除
def f = Face.get(1)
f.nose.delete()
f.delete()

如果在删除Face实例的时候,我们不想自动删除和face关联的nose实例,需要将belongsTo修改一下,代码如下:

<!-- lang:groovy -->
class Face {
    Nose nose
}

class Nose {
    static belongsTo = Face
}

注意:我们没有用明确的语法声明映射关系,所以这个关联是单向的,并且不能设置成双向,否则会出现映射错误。

##One to Many##

一对多的关系是指,当一个类(比如Author)拥有另一个类(Book)的多个实例这种情况。在Grails中,你可以使用 hasMany 来定义这种关联

<!-- lang: groovy -->
class Author {
    static hasMany = [ books : Book ]
    String name
}

class Book {
   String title
}

这样我们有了一个一对多的单向关联。Grails在数据库级别将默认使用外键映射来映射这种关联关系。Grails 将会根据hasMany 设置为domain类自动注入一个类型为java.util.Set的属性。这个可以被用来遍历集合,代码如下:

<!-- lang: groovy -->
def a = Author.get(1)
a.books.each {
    println it.title
}

上面的代码遍历所有a作家的所著的所有图书。在上面的关联关系下,book对象可以级联保存和更新,但是不能级联删除,如果删除author的某个实例还要将和这个实例相关的book也删除,则需要使用belongTo关键字,代码如下:

<!-- lang: groovy -->
class Author {
    static hasMany = [ books : Book ]
   String name
}

class Book {
   static belongsTo = [author:Author]
   String title
}

其数据操作方法就可以参考OneToOne了。

在数据映射对象中,如果对象有多个属性有映射关系,则需要使用mappedBy关键字来指定他们分别映射的是哪个集合,代码如下:

<!-- lang: groovy -->
class Airport {
    static hasMany = [flights:Flight] //一个机场有多条航线
    static mappedBy = [flights:"departureAirport"] //离港机场
}
class Flight { //一条航线涉及到入港机场和出港机场
    Airport departureAirport
    Airport destinationAirport
}

一条航线涉及到入港机场和出港机场,针对哪条航线的入港机场是什么,出港机场是什么,其映射关系需要指定。

更为明细的指定如下:

<!-- lang: groovy -->
class Airport {
    static hasMany = [outboundFlights:Flight, inboundFlights:Flight] //入站航班和出站航班
    static mappedBy = [outboundFlights:"departureAirport", inboundFlights:"destinationAirport"]
}
class Flight {
    Airport departureAirport
    Airport destinationAirport
}

##Many to Many##

这种关联需要在关联的两方都定义hasMany,并在关联的被拥有方定义belongsTo(可用来指某物属于某人):

<!-- lang: groovy -->
class Book {
   static belongsTo = Author
   static hasMany = [authors:Author]
   String title
}
class Author {
   static hasMany = [books:Book]
   String name
}

Grials在数据库层使用连接表来映射多对多关联。关联的拥有方,在这里是Author,负责持久化这个关联,并且它是唯一可以级联保存对方的一方。

比如下面的代码可以工作,并且会级联保存:

<!-- lang: groovy -->
new Author(name:"Stephen King")
    .addToBooks(new Book(title:"The Stand"))
    .addToBooks(new Book(title:"The Shining"))		
    .save()

但是下面的代码只保存 Book 而不保存authors!

<!-- lang: groovy -->
new Book(name:"Groovy in Action")
    .addToAuthors(new Author(name:"Dierk Koenig"))
    .addToAuthors(new Author(name:"Guillaume Laforge"))		
    .save()

这正是我们期望的行为,跟Hibernate中一样,多对多关联中只有一方可以管理关联。

© 著作权归作者所有

共有 人打赏支持
寡鸡蛋
粉丝 12
博文 51
码字总数 19107
作品 0
中山
售前工程师
Groovy&Grails-代码剪辑-复用约束

假如我们在程序中使用了一个command对象,在Grails2.0之后的版本中引入了新的机制,可以复用constraints块的代码,重用约束,如下面的例子: 上面的代码时一个标准的domain对象,假如我们要在...

寡鸡蛋
2013/11/01
0
0
Groovy&Grails-代码剪辑-domain对象保存

默认domain对象中,没有在constraints中声明的属性都是必填项。 如User对象 测试代码 会出现用例测试错误,将所有字段都填值后,测试代码运行正常 在constraints中声明lastname允许为空 再测...

寡鸡蛋
2013/10/08
0
0
Groovy&Grails-代码剪辑-domain对象继承

默认的对象继承在数据库中的表现也是将表用外键进行关联管理,当然可以修改默认的配置,而且为了保持对象和数据表的一致性,这里建议修改成一张表来表示继承对象 对象继承 数据表外键关联 用...

寡鸡蛋
2013/10/03
0
0
Groovy&Grails-代码剪辑-初始化

开发时需要初始化一些特定的代码,测试时需要初始化一些测试代码,在生产环境时需要初始化一些运行时环境代码,在Grails的bootstrap中可以根据不同的环境进行特定的植入,代码如下:...

寡鸡蛋
2013/10/03
0
0
Groovy&Grails-代码剪辑-日志跟踪

任何开发都需要跟踪一些调试信息,避免频繁的使用Debug模式,我们会在方法中放入一些info,执行过程中打印到后台,Grails使用的是log4j作为日志框架,所以和在Java开发中的使用方法是一样的,...

寡鸡蛋
2013/10/05
0
0
Groovy&Grails-代码剪辑-日期时间格式化

使用grails标签获取到日期时间后是格林威治时间样式:2013-09-27 13:57:37 CST ,所以显示的时候需要格式化一下,格式化代码如下: 但是使用JSON获取到数据后,不是用标签获取到的,所以需要在生成...

寡鸡蛋
2013/09/27
0
0
Nebula3中的骨骼动画: Animation子系统

就像CoreAnimation 中提到的, Nebula2动作系统急需一个全新的设计和编码. 在《龙歌》的开发和另一个针对表情动画的研究中, 我们不得不为这个天生不足的系统加入新的特性. 最后系统勉强可以正...

长平狐
2012/11/12
50
0
Groovy&Grails-代码剪辑-直接使用数据表

其实现在开发过程中,大部分人对面向对象的概念一点都不感冒.虽然这玩意发展了这么久,在国内的软件公司确不为所动.估计是工期赶的紧,所以大部分功能就一条SQL搞定比较干脆.在Grails中其实不提...

寡鸡蛋
2013/09/30
0
0
Neubla3中的骨骼动画: CoreAnimation子系统

最早的一个设计是把动作代码分成两个子系统. CoreAnimation作为低层系统, 只为更复杂的高层动作系统提供简单而又高性能的”砖瓦”. 高层Animation子系统以CoreAnimation为基础, 提供了像抽像...

长平狐
2012/11/12
119
0
Groovy&Grails-代码剪辑-修改主键

有的时候安全起见需要修改ID的生成方式,有时候因为特定的原因对ID字段需要自定义生成,更多的时候是比较无聊。修改ID字段的默认值 使用UUID方式生成ID 自定义ID的值 确实够无聊的。 附带一些...

寡鸡蛋
2013/10/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

【面试题】盲人坐飞机

有100位乘客乘坐飞机,其中有一位是盲人,每位乘客都按自己的座位号就坐。由于盲人看不见自己的座位号,所以他可能会坐错位置,而自己的座位被占的乘客会随便找个座位就坐。问所有乘客都坐对...

garkey
今天
0
0
谈谈神秘的ES6——(二)ES6的变量

谈谈神秘的ES6——(二)ES6的变量 我们在《零基础入门JavaScript》的时候就说过,在ES5里,变量是有弊端的,我们先来回顾一下。 首先,在ES5中,我们所有的变量都是通过关键字var来定义的。...

JandenMa
今天
1
0
arts-week1

Algorithm 594. Longest Harmonious Subsequence - LeetCode 274. H-Index - LeetCode 219. Contains Duplicate II - LeetCode 217. Contains Duplicate - LeetCode 438. Find All Anagrams ......

yysue
今天
0
0
NNS拍卖合约

前言 关于NNS的介绍,这里就不多做描述,相关的信息可以查看NNS的白皮书http://doc.neons.name/zh_CN/latest/nns_background.html。 首先nns中使用的竞价货币是sgas,关于sgas介绍可以戳htt...

红烧飞鱼
今天
1
0
Java IO类库之管道流PipeInputStream与PipeOutputStream

一、java管道流介绍 在java多线程通信中管道通信是一种重要的通信方式,在java中我们通过配套使用管道输出流PipedOutputStream和管道输入流PipedInputStream完成线程间通信。多线程管道通信的...

老韭菜
今天
0
0
用Python绘制红楼梦词云图,竟然发现了这个!

Python在数据分析中越来越受欢迎,已经达到了统计学家对R的喜爱程度,Python的拥护者们当然不会落后于R,开发了一个个好玩的数据分析工具,下面我们来看看如何使用Python,来读红楼梦,绘制小...

猫咪编程
今天
1
0
Java中 发出请求获取别人的数据(阿里云 查询IP归属地)

1.效果 调用阿里云的接口 去定位IP地址 2. 代码 /** * 1. Java中远程调用方法 * http://localhost:8080/mavenssm20180519/invokingUrl.action * @Title: invokingUrl * @Description: * @ret......

Lucky_Me
今天
1
0
protobuf学习笔记

相关文档 Protocol buffers(protobuf)入门简介及性能分析 Protobuf学习 - 入门

OSC_fly
昨天
0
0
Mybaties入门介绍

Mybaties和Hibernate是我们在Java开发中应用的比较多的两个ORM框架。当然,目前Mybaties正在慢慢取代Hibernate,这是因为相比较Hibernate而言Mybaties性能更好,响应更快,更加灵活。我们在开...

王子城
昨天
2
0
编程学习笔记之python深入之装饰器案例及说明文档[图]

编程学习笔记之python深入之装饰器案例及说明文档[图] 装饰器即在不对一个函数体进行任何修改,以及不改变整体的原本意思的情况下,增加函数功能的新函数,因为这个新函数对旧函数进行了装饰...

原创小博客
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部