Grails对象关联映射(GORM)⼆ Groovy 的多⾏字符串对HQL查询⽆效
分页和排序
使⽤HQL查询的时候你也可以进⾏分页和排序。要做的只是简单指定分页和排序参数作为⼀个散列在⽅法的末尾调⽤:
def results =
Book.findAll("from Book as b where b.title like 'Lord of the%' order by b.title asc",
[max:10, offt:20])
接下来的章节覆盖更多⾼级的GORM使⽤ 包括 缓存、定制映射和事件。
GORM⽀持事件注册,只需要将事件作为⼀个闭包即可,当某个事件触发,⽐如删除,插⼊,更新。The following is a list of supported events下⾯就是所⽀持事件的列表:
beforeInrt - 对象持久到数据之前执⾏
beforeUpdate - 对象被更新之前执⾏
beforeDelete - 对象被删除之前执⾏
afterInrt - 对象持久到数据库之后执⾏
afterUpdate - 对象被更新之后执⾏
afterDelete - 对象被删除之后执⾏
onLoad - 对象从数据库中加载之后执⾏
为了添加⼀个事件需要在你的领域类中添加相关的闭包。
事件类型
beforeInrt事件
当⼀个对象保存到数据库之前触发
class Person {
Date dateCreated
def beforeInrt = {
dateCreated = new Date()
}
}
beforeUpdate事件
当⼀个对象被更新之前触发
def beforeInrt = {
dateCreated = new Date()
}
def beforeUpdate = {
lastUpdated = new Date()
}
}
beforeDelete事件
当⼀个对象被删除以后触发.
class Person {
String name
Date dateCreated
Date lastUpdated
def beforeDelete = {
new ActivityTrace(eventName:"Person Deleted",data:name).save()
}
}
onLoad事件
当⼀个对象被加载之后触发:
class Person {
String name
Date dateCreated
Date lastUpdated
def onLoad = {
name = "I'm loaded"
}
}
⾃动时间戳
上⾯的例⼦演⽰了使⽤事件来更新⼀个 lastUpdated 和 dateCreated 属性来跟踪对象的更新。事实上,这些设置不是必须的。通过简单的定义⼀个 lastUpdated 和 dateCreated 属性,GORM会⾃动的为你更新。
如果,这些⾏为不是你需要的,可以屏蔽这些功能。如下设置:
static mapping = {
autoTimestamp fal
}
}
Grails 的域对象可以映射到许多遗留的模型通过 关系对象映射域语⾔。接下来的部分将带你领略它是可能的通过ORM DSL。
这是必要的,如果你⾼兴地坚持以约定来定义GORM对应的表,列名等。你只需要这个功能,如果你需要定制GORM 映射到遗留模型或进⾏缓存
⾃定义映射是使⽤静态的mapping 块定义在你的域类中的:
class Person {
..
static mapping = {
}
}
表名
类映射到数据库的表名可以通过使⽤ table关键字来定制:
class Person {
..
static mapping = {
table 'people'
}
}
在上⾯的例⼦中,类会映射到 people 表来代替默认的 person表.
列名
同样,也是可能的定制某个列到数据库。⽐如说,你想改变列名例⼦如下:
class Person {
String firstName
static mapping = {
table 'people'
firstName column:'First_Name'
}
}
在这个例⼦中,你定义了⼀个column块,此块包含的⽅法调⽤匹配每⼀个属性名称 (in this ca firstName). 接下来使⽤命名的 column,来指定字段名称的映射.
列类型
GORM还可以通过DSL的type属性来⽀持Hibernate类型. 包括特定Hibernate的 的⼦类, which allows complete customization of how a type is persisted. ⽐如,有⼀个 PostCodeType 你可以象下⾯这样使⽤:
class Address {
String number
String postCode
static mapping = {
postCode type:PostCodeType
}
}
另外如果你想将它映射到Hibernate的基本类型⽽不是Grails的默认类型,可以参考下⾯代码:
class Address {
String number
String postCode
static mapping = {
postCode type:'text'
}
}
上⾯的例⼦将使 postCode 映射到数据库的SQL TEXT或者CLOB类型.
See the Hibernate documentation regarding for further information.
⼀对⼀映射
在关联中,你也有机会改变外键映射联系,在⼀对⼀的关系中,对列的操作跟其他常规的列操作并⽆⼆异,例⼦如下:
class Person {
String firstName
Address address
static mapping = {
table 'people'
firstName column:'First_Name'
address column:'Person_Adress_Id'
}
}
默认情况下 address 将映射到⼀个名称为 address_id 的外键. 但是使⽤上⾯的映射,我们改变外键列为 Person_Adress_Id.
⼀对多映射
在⼀个双向的⼀对多关系中,你可以象前节中的⼀对⼀关系中那样改变外键列,只需要在多的⼀端中改变列名即可。然⽽,在单向关联中,外键需要在关联⾃⾝中(即⼀的⼀端-译者注)指定。⽐如,给定⼀个单向⼀对多联系 Person 和 Address 下⾯的代码会改变 address 表中外键:
class Person {
String firstName
static hasMany = [address:Address]
static mapping = {
table 'people'
firstName column:'First_Name'
address column:'Person_Address_Id'
}
}
如果你不想在 address 表中有这个列,可以通过中间关联表来完成,只需要使⽤ joinTable 参数即可:
class Person {
String firstName
static hasMany = [address:Address]
static mapping = {
table 'people'
firstName column:'First_Name'
address joinTable:[name:'Person_Address', key:'Person_Id', column:'Address_Id']
}
}
多对多映射
默认情况下, Grails中多对多的映射是通过中间表来完成的. 以下⾯的多对多关联为例:
class Group {
…
static hasMany = [people:Person]
}
class Person {
…
static belongsTo = Group
static hasMany = [groups:Group]
}
在上⾯的例⼦中Grails将会创建⼀个 group_person 表包含外键 person_id 和 group_id 对应 person 和 group 表. 假如你需要改变列名,你可以为每个类指定⼀个列映射.
class Group {
…
static mapping = {
people column:'Group_Person_Id'
}
}
class Person {
…
static mapping = {
groups column:'Group_Group_Id'
}
}
你也可以指定中间表的名称: