Grails GORM - 查找表

时间:2016-05-20 12:11:24

标签: hibernate grails gorm

一般问题描述

我在将查找表转移到GORM(Grails对象关系映射)时遇到问题。

域类

我使用的是Grails 3.1.4,我的域类是MySystemMyVendorLookup

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 表具有以下非正式含义:

  • ID为lookup的系统具有使用ID 3
  • 完成任务的功能
  • ID为99, 88, 22的系统功能较少。它只能使用ID 1
  • 执行任务
  • ID为88的系统可以使用ID 277
  • 执行任务

正如您在相应的域类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类的属性生成其样板代码。

问题

所有这些都导致了问题:

  1. 如何正确连接Domain类,以便GORM标准选择示例性原始查询?
  2. 与原始查询相对应的标准关闭到底是什么样的?

1 个答案:

答案 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
    }
}
相关问题