Grails 关系 m:n:n
Grails Relation m:n:n
我们在 grails 下使用现有的 mysql 数据库,其中包含 m:n 关系。这里没问题。但是现在我们的情况是我必须添加第二个 n 关系条目,它链接到同一个 table 并且必须关联到第一个 n 条目。
如果是数据库,我会简单地创建一个 table,它看起来像:
field m_id -> links to m table
field n_id1 -> links to n table
field n_id2 -> links to n table
但这如何在 grails 域中表示 class?
可能已经在某处找到了答案,但我搜索并没有成功,可能是搜索词创意不足
编辑:
试图澄清这个问题:我们有一个多对多的关系,但是在一侧有两个项目,它们必须保持相互关联(并且还必须清楚哪个是原始的和哪个是替换项),因此不能将它们分成两个单独的条目进入关系。
嗯...试想赛车手提名一系列比赛,每个提名都必须包含车手和他的替补。比赛是 m(左手),车手是 n1,替补是 n2。 (找例子真的好辛苦。。。)
编辑:
巧合的是,我发现 this question 解决了同样的问题,但也没有解决。
看看文档,很清楚:
http://grails.github.io/grails-doc/2.5.0/guide/GORM.html#gormAssociation
无论如何,我不确定我是否理解您的意图,但让我们试试吧。
如果是一对一的关系,你可以简单地做这样的事情:
class DomainA {
DomainB domainB
DomainC firstDomainC
DomainC secondDomainC
}
class DomainB {
}
class DomainC {
}
这将在 "domain_a" table 中创建以下字段:
- "domain_b_id"
- "first_domain_c_id"
- "second_domain_c_id"
如果它是从 DomainA 到 DomainB 和 DomainC 的一对多关系,在 DomainA 中有两个不同的 DomainC 集合,您必须在 DomainC 中有两个不同的 DomainA 属性才能映射它。
文档中机场和航班的示例:
class Airport {
static hasMany = [outboundFlights: Flight, inboundFlights: Flight]
static mappedBy = [outboundFlights: "departureAirport",
inboundFlights: "destinationAirport"]
}
class Flight {
Airport departureAirport
Airport destinationAirport
}
航班需要Airport属性才能区分是哪一个映射正确hasMany collection in Airport。
编辑:赛车手示例
Grails 支持多对多关系,但其中一端必须是主要端,而另一端必须另外有一个 belongsTo。虽然事实并非如此,因为 race 不属于 driver,driver 也不属于 race。
我会使用与 属性 的关系:"drives" 与 属性 "mainDriver"。
那不能直接映射,你需要为关系使用域:
class Race {
static hasMany = [ participants: DriverRace ]
def mainDrivers() {
getDrivers( false )
}
def substitutes() {
getDrivers( false )
}
private getDrivers( mainDriver ) {
DriverRace.withCriteria {
eq( "race", this )
eq( "mainDriver", mainDriver )
}.collect { it.driver }
}
}
class Driver {
static hasMany = [ races: DriverRace ]
}
class DriverRace {
static belongsTo = [ race: Race, driver: Driver ]
boolean mainDriver
}
我们认为我们能够通过在(左侧)域 m 的映射 属性 中插入对 domain/table n 的第二个引用来解决问题。然后 grails 似乎在关系的右侧放置了对 n 的第二个引用。但事实证明那是一个充满希望的周末梦想。
我们在 grails 下使用现有的 mysql 数据库,其中包含 m:n 关系。这里没问题。但是现在我们的情况是我必须添加第二个 n 关系条目,它链接到同一个 table 并且必须关联到第一个 n 条目。
如果是数据库,我会简单地创建一个 table,它看起来像:
field m_id -> links to m table
field n_id1 -> links to n table
field n_id2 -> links to n table
但这如何在 grails 域中表示 class?
可能已经在某处找到了答案,但我搜索并没有成功,可能是搜索词创意不足
编辑:
试图澄清这个问题:我们有一个多对多的关系,但是在一侧有两个项目,它们必须保持相互关联(并且还必须清楚哪个是原始的和哪个是替换项),因此不能将它们分成两个单独的条目进入关系。
嗯...试想赛车手提名一系列比赛,每个提名都必须包含车手和他的替补。比赛是 m(左手),车手是 n1,替补是 n2。 (找例子真的好辛苦。。。)
编辑:
巧合的是,我发现 this question 解决了同样的问题,但也没有解决。
看看文档,很清楚: http://grails.github.io/grails-doc/2.5.0/guide/GORM.html#gormAssociation
无论如何,我不确定我是否理解您的意图,但让我们试试吧。
如果是一对一的关系,你可以简单地做这样的事情:
class DomainA {
DomainB domainB
DomainC firstDomainC
DomainC secondDomainC
}
class DomainB {
}
class DomainC {
}
这将在 "domain_a" table 中创建以下字段:
- "domain_b_id"
- "first_domain_c_id"
- "second_domain_c_id"
如果它是从 DomainA 到 DomainB 和 DomainC 的一对多关系,在 DomainA 中有两个不同的 DomainC 集合,您必须在 DomainC 中有两个不同的 DomainA 属性才能映射它。
文档中机场和航班的示例:
class Airport {
static hasMany = [outboundFlights: Flight, inboundFlights: Flight]
static mappedBy = [outboundFlights: "departureAirport",
inboundFlights: "destinationAirport"]
}
class Flight {
Airport departureAirport
Airport destinationAirport
}
航班需要Airport属性才能区分是哪一个映射正确hasMany collection in Airport。
编辑:赛车手示例
Grails 支持多对多关系,但其中一端必须是主要端,而另一端必须另外有一个 belongsTo。虽然事实并非如此,因为 race 不属于 driver,driver 也不属于 race。 我会使用与 属性 的关系:"drives" 与 属性 "mainDriver"。 那不能直接映射,你需要为关系使用域:
class Race {
static hasMany = [ participants: DriverRace ]
def mainDrivers() {
getDrivers( false )
}
def substitutes() {
getDrivers( false )
}
private getDrivers( mainDriver ) {
DriverRace.withCriteria {
eq( "race", this )
eq( "mainDriver", mainDriver )
}.collect { it.driver }
}
}
class Driver {
static hasMany = [ races: DriverRace ]
}
class DriverRace {
static belongsTo = [ race: Race, driver: Driver ]
boolean mainDriver
}
我们认为我们能够通过在(左侧)域 m 的映射 属性 中插入对 domain/table n 的第二个引用来解决问题。然后 grails 似乎在关系的右侧放置了对 n 的第二个引用。但事实证明那是一个充满希望的周末梦想。