当一个类(如Author),拥有另外一个类(如Book),就是一个one-to-many关系。在 Grails中,你可以用hasMany 来定义这种关系:
class Author {
static hasMany = [books: Book]
String name
}
class Book {
String title
}
在这种情况下我们拥有一个单向的 one-to-many。 Grails默认情况下, 这种映射关系是连接一张表。
ORM DSL允许使用外键关联,而不是单向关系映射。
Grails 将依赖于hasMany设置,自动将一个java.util.Set属性类型注入到domain class中,这可以用来遍历集合:
def a = Author.get(1)
for (book in a.books) {
println book.title
}
Grails默认的获取策略是使用“lazy”加载,这意味着第一次访问该集合将被延迟初始化。如果你不小心,这可能会导致 n+1 problem 问题。
如果你需要采取"eager"获取策略,你可以使用 ORM DSL 或者指定急切抓取就像一个 query的一部分。
默认的级联行为是级联保存和级联更新,但不包括级联删除,除非指定了 belongsTo。
class Author {
static hasMany = [books: Book]
String name
}
class Book {
static belongsTo = [author: Author]
String title
}
如果你有两个相同类型的属性在one-to-many的 many一方,你必须使用mappedBy 来指定到不同的集合映射:
class Airport {
static hasMany = [flights: Flight]
static mappedBy = [flights:"departureAirport"]
}
class Flight {
Airport departureAirport
Airport destinationAirport
}
如果你有多个集合映射到many方不同的属性,这样做是正确的:
class Airport {
static hasMany = [outboundFlights: Flight,inboundFlights: Flight]
static mappedBy = [outboundFlights:"departureAirport",
inboundFlights:"destinationAirport"]
}
class Flight {
Airport departureAirport
Airport destinationAirport
}