Grails:许多桌子上的投影?

Đin*_*hâu 8 grails criteria projection grails-orm

我在Grails中有一些投影问题.能帮我复习一下并为我提出解决方案吗?

  1. 我想查询许多表上的数据,这些表具有多对一的关系,并在两个表上的某些属性上进行投影.例如:

    class Person {
        int id
        String name
        String address
        static hasMany = [cars : Car]
    }
    
    class Car {
       int id
       String brand
       long price
       Person owner
       static belongsTo = [owner : Person]
    }
    
    Run Code Online (Sandbox Code Playgroud)

    那么,我如何只使用一个查询withCriteria(应用投影)来获取指定汽车的信息(包括品牌,价格和所有者名称)?是否可以使用:

    Car.withCriteria {
         projections {
             property("brand")
             property("price")
             property("owner.name")
        }
        eq("id", carId)
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我可以使用投影获取一个指定人员的信息以及他所有车辆的名称吗?例如:[01,Perter,01 Street A,[Mercedes,Toyota,Ducatti]]?

  3. 特殊情况:(与上述人员类别)
    一个人可以加入许多组织,组织可以有一个"父"组织(反之亦然,一个组织可以有许多其他依赖组织).但是有一条规则:一个人只能加入一个特定组织的一个儿童组织.因此,对于给定的组织O和人P,获得P的信息的最快方式是什么,以及具有P作为成员的O的依赖组织的名称.我更喜欢使用Grails投影.

    这是数据模型:

    class Person {
        int id
        String name
        String address
        static hasMany = [joinedOrgs : Organization] 
    }
    
    class Organization {
        int id
        String name
        Organization parentOrg
        static hasMany = [members : Person, childOrgs : Organization]
    }
    
    Run Code Online (Sandbox Code Playgroud)

我是Grails的新手,我想更多地了解GORM.非常感谢你的帮助.

Muh*_*lib 9

试试这个

def results =  Car.createCriteria().list() { 
    createAlias('owner','owner')
    projections { 
        property('owner.name', 'owner.name') 
        property('brand','brand')
        property('price','price')
    }
}
Run Code Online (Sandbox Code Playgroud)


Hoà*_*ong 1

对于(1)和(2),我不知道是否有一种方法可以只用 1 个条件查询来完成您想要的操作,但替代方法似乎更简单和自然。对于(1):

def car = Car.get(carId)
def owners = car.owner?.name
Run Code Online (Sandbox Code Playgroud)

对于(2)

def person = Person.get(personId)
def cars = person.cars*.name
Run Code Online (Sandbox Code Playgroud)

关于(3),这是一种设计问题。您当前的域设计没有反映您所描述的规则,因此很难维持该约束。您可以考虑映射 PersonOrganization 表并将childrenOrganization 设置为瞬态属性。例如:

class Organization {
    int id
    String name
    Organization parent
    static transients = ['children']
    ...

    Boolean children() {
        def children = Organization.createCriteria().list() { 
            eq ('parent', this) 
        }
        return children
    }
}
Run Code Online (Sandbox Code Playgroud)

之后,您可以使用像 getAllAncestors() 这样的回溯函数来确定组织的所有父层次结构,并在人员组织列表中查找它。这似乎不是最好的方法,但这是一种可能的方法。