我在将查找表转移到GORM(Grails对象关系映射)时遇到问题。
我使用的是Grails 3.1.4,我的域类是MySystem
,MyVendor
和Lookup
:
class MySystem {
String productName
MyVendor vendor
static belongsTo = [myVendor: MyVendor]
static mapping = {
id column: "product_id", generator: "assigned"
table 'my_system_table'
version false
}
static constraints = {
productName nullable: true
}
}
class MyVendor {
String vendorName
static hasMany = [mySystems: MySystem]
static mapping = {
id column: "vendor_id", generator: "assigned"
version false
}
static constraints = {
vendorName nullable: true
}
}
class Lookup implements Serializable {
Integer systemId
Integer someIdA
Integer someIdB
int hashCode() {
def builder = new HashCodeBuilder()
builder.append systemId
builder.append someIdA
builder.append someIdB
builder.toHashCode()
}
boolean equals(other) {
if (other == null) return false
def builder = new EqualsBuilder()
builder.append systemId, other.systemId
builder.append someIdA, other.someIdA
builder.append someIdB, other.someIdB
builder.isEquals()
}
static mapping = {
id composite: ["systemId", "someIdA", "someIdB"]
version false
}
}
mysystem
表如下所示:
mysystem
product_id vendor_id product_name
1 1 ProductA
2 1 ProductB
3 3 ProductC
... ... ...
99 3 ProductAB
product_id
列是 primary_key ,一个product_id
可以拥有一个供应商,通过在{{中定义static belongsTo = [myVendor: MyVendor]
来反映在GORM中1}}域类。
MySystem
表如下所示:
myvendor
在此表中,主键为myvendor
vendor_id vendor_name
1 VendorA
2 VendorB
3 VendorC
... ...
,并且通过查看此表无法察觉到vendor_id
表的逻辑链接。只有通过GORM才能通过将mysystem
设置为属性来创建mysystem
的逻辑链接。
static hasMany = [mySystems: MySystem]
表如下所示:
lookup
这个所谓的lookup
system_id some_id_a some_id_b
3 99 1
3 88 1
3 22 1
... ... ...
1 77 1
2 88 1
2 22 1
表具有以下非正式含义:
lookup
的系统具有使用ID 3
99, 88, 22
的系统功能较少。它只能使用ID 1
88
的系统可以使用ID 2
和77
正如您在相应的域类22
中看到的那样,主键是所有列Lookup
上的元组
当我想找到能够使用id (system_id,some_id_a,some_id_b)
和22
执行任务的系统时,我可以像这样查询我的数据库:
88
本帖中给出的示例集的结果将是:
Select system_id from lookup a where some_id_a= 22 and some_id_b= 1 and
Exists (Select system_id from lookup where
some_id_a= 88 and system_id = a.system_id)
当我想找到可以使用ids system_id
2
3
执行任务的系统时,我可以针对我的数据库执行以下查询:
99,88,22
这个查询会给我:
Select system_id from lookup a where some_id_a = 99 and some_id_b = 1 and
Exists (Select system_id from lookup where
some_id_a = 88 and system_id = a.system_id) and
Exists (Select system_id from lookup where
some_id_a = 22 and system_id = a.system_id)
我的原始查询以及代码中针对数据库的HQL查询工作,但我无法找到system_id
3
Domain类的正确GORM属性映射,因此构建GORM queries using criterias可以正常工作。
例如,我可以使用criterias以下列方式使用此Service类:
Lookup
这只会给我一个数据库中id为1的产品。
我不能做的是以下内容:
class MySystemService {
def myMethod() {
def criteria = MySystem.createCriteria()
def results = criteria.list {
eq("productId", 1)
}
return results
}
}
它给了我这个错误:
class MySystemService {
def myMethod() {
def criteria = MySystem.createCriteria()
def results = criteria.list {
lookup{
eq("systemId", 1)
}
}
return results
}
}
我知道这是因为我无法将Domain类与映射一起正确连接。由于Grails无法为Domain类的属性生成其样板代码。
所有这些都导致了问题:
答案 0 :(得分:0)
为了按预期使用GORM,请考虑对象属性,而不是表列。在GORM中,域类通过属性关联,这会影响Hibernate生成SQL查询的方式。我在this文章中详细介绍了一下。这是你可以做的:
class MySystem {
String productName
MyVendor vendor
static hasMany = [lookups: Lookup]
static belongsTo = [myVendor: MyVendor]
static mapping = {
id column: "product_id", generator: "assigned"
table 'my_system_table'
version false
}
static constraints = {
productName nullable: true
}
}
class Lookup implements {
Integer someIdA
Integer someIdB
static belongsTo = [mySystem: MySystem]
static constraints = {
someIdA unique: 'someIdB'
}
}
class MySystemService {
def myMethod() {
def criteria = MySystem.createCriteria()
def results = criteria.list {
lookups {
eq("someIdA", 1)
}
}
return results
}
}