博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Groovy&Grails-代码剪辑-对象关系
阅读量:7225 次
发布时间:2019-06-29

本文共 3052 字,大约阅读时间需要 10 分钟。

hot3.png

One To One

一张脸上只有一个鼻子。

class Face { Nose nose}class Nose {}

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

class Face { Nose nose}class Nose { Face face}

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

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

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

new Face(nose:new Nose()).save()

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

new Nose(face:new Face()).save() // 这样会报错

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

def f = Face.get(1)f.delete() // Face和Nose实例都会被删除

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

// 如果没有belongsTo会报错,因为有约束def f = Face.get(1)f.delete()// 所以没有belongsTo时需要手工删除def f = Face.get(1)f.nose.delete()f.delete()

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

class Face { Nose nose}class Nose { static belongsTo = Face}

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

##One to Many##

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

class Author { static hasMany = [ books : Book ] String name}class Book { String title}

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

def a = Author.get(1)a.books.each { println it.title}

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

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

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

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

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

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

更为明细的指定如下:

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(可用来指某物属于某人):

class Book { static belongsTo = Author static hasMany = [authors:Author] String title}class Author { static hasMany = [books:Book] String name}

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

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

new Author(name:"Stephen King") .addToBooks(new Book(title:"The Stand")) .addToBooks(new Book(title:"The Shining")) .save()

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

new Book(name:"Groovy in Action") .addToAuthors(new Author(name:"Dierk Koenig")) .addToAuthors(new Author(name:"Guillaume Laforge")) .save()

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

转载于:https://my.oschina.net/65304586/blog/165698

你可能感兴趣的文章
ASP.NET MVC验证 - 自定义验证规则、验证2个属性值不等【待验证】
查看>>
Android blueZ HCI(一个):hciconfig实施和经常使用
查看>>
微信公众号怎么推送消息_微信公众号发送消息
查看>>
电商指尖---(9).net发展Solr中间Facet特征
查看>>
SQList3 and SQL入门学习笔记
查看>>
jQuery 找到当前元素之前最后一次出现的某个同辈元素
查看>>
我如何调优SQL Server查询
查看>>
读取文档数据的各列的每行中
查看>>
Android - 警告:it is always overridden by the value specified in the Gradle build script
查看>>
分布式系统解决方案
查看>>
采用malloc分别分配2KB个人空间,然后,realloc调整到6KB、1MB、3MB、10MB场地,分别这五内存“A”、“B”、“C”、“D”、“E”灌装...
查看>>
欧拉工程第63题:Powerful digit counts
查看>>
Android实例-程序界面内截取屏幕(XE8+小米2)
查看>>
安卓Android面试题大全
查看>>
ListView item 中TextView 如何获取长按事件
查看>>
移动前端开发之viewport的深入理解
查看>>
C# JAVAMemory model
查看>>
[Angular + Webpack] ocLazyLoad compoment
查看>>
[转]响应式WEB设计学习(1)—判断屏幕尺寸及百分比的使用
查看>>
Rectangles Area Sum
查看>>