【问题标题】:GORM Querying where filter is not a direct attribute of a classGORM查询过滤器不是类的直接属性
【发布时间】:2010-10-22 09:30:42
【问题描述】:

我正在尝试找出使用 Grails GORM 执行某种类型查询的最有效/最有效的方法。

这是我想以多对一关系查询所有子项/链接项的场景。这是一种单向关系,多方使用它所链接的事物的 id。

一个例子是一个学年和该学年的学期之间的关系。在学期表中,表中存储了学期所属学年的id。然而,学年没有任何东西可以链接到属于它的学期。这样做是为了保持学期数的灵活性。我希望做的是使用 HQL 之类的东西来检索所有拥有相同学年的学期。在常规 SQL 中,我们可以使用学期表的学年 id 列过滤行。在 HQL 中,它并不那么简单。学年 ID 不可用作域类的属性。相反,Hibernate 只是使用它来加载实际的学年对象。

在这种情况下应该像下面这样工作吗?

select from Semester as s where s.year.id = ?

在这种情况下,保存学年的学期域类的属性称为年。该查询使用 year 属性和那一年的 id 并使用它来过滤学期。

这只是一个例子,但我正在开发的系统包含不止一个类似的安排,需要加载一组具有相同链接域对象的域对象。

可能有一种更有效/更有效的方法来做到这一点。一个示例是从域类中获取实际的学年 id 值。然而,这意味着同一列映射到域类的多个属性。这可能不是必需的,但它是解决此类问题的另一种可能方式。

有一些 Hibernate 经验,但是当您想做更多不寻常的事情时,一些问题在 Hibernate 中会变得复杂。

【问题讨论】:

    标签: hibernate grails hql grails-orm


    【解决方案1】:

    这看起来像基本的 1:M 关系,由 belongsTo/hasMany 映射处理。 它不会使父表保留任何附加数据。只要有域对象:

    class AcademicYear {
        static hasMany = [semesters: Semester]
    }
    
    class Semester {
        static belongsTo = AcademicYear
    }
    

    Semester 神奇地具有“academicYear”属性,您可以参考。一切,就这样做吧:

    AcademicYear y = AcademicYear.findByYear(2010)
    Semester s = Semester.get(1)
    y.addToSemesters(s)
    y.semesters.each{ println it }
    String year = s.academicYear.name
    def a = s.academicYear.id
    

    首先在“grails 控制台”中尝试并享受。

    【讨论】:

      【解决方案2】:

      虽然 gorm 是 hibernate 之上的另一层,但它为通常的场景提供了高效的条件查询和动态查找器,当涉及到不寻常的场景时,我们必须查看条件查询。而更不寻常的场景,我们必须看hql,更复杂的情况我们也可以写基本的sql。

      以下是可用于实现一种或其他类型的查询级别任务的上层不同方法。

      假设:我们有一个 Employee 域,如下所示:

      class Employee{
      String name
      int age
      Designation designation
      
      static hasMany = [teams:Team]
      }
      
      1. GORM 动态查找器:

         Employee.findByName("Ajay")
        
      2. 条件查询:

        Employee.createCriteria().list {
                eq 'name', 'Ajay'   
        }
        
      3. where 子句:

        Employee.where {
            name == 'ajay' && (age > 25 && age < 30)
        }.list()
        
      4. HQL:

        Employee.findAll('from Employee as e where e.name = :name', [name: 'Ajay'])
        
      5. 基础 sql:

        String query = $/
        SELECT * from employee e
        WHERE e.name = :name
        /$  
        new Employee()
        .domainClass
        .grailsApplication
        .mainContext
        .sessionFactory
        .currentSession
        .createSQLQuery(query)
            .setString('name', 'Ajay')
            .list()
        

      下面是更细化的层次结构,其中“是”表示合适或适用:

                          dynamic finder          where clause    criteria    HQL     SQL
      
          simple queries         yes                Yes             Yes        Yes    Yes
      
          complex filters                           Yes             Yes        Yes    Yes
      
          associations                              Yes             Yes        Yes    Yes
      
          property comparisons                      Yes             Yes        Yes    Yes
      
          some subqueries                           Yes             Yes        Yes    Yes
      
          eager fetches w/ complex filters                          Yes        Yes    Yes 
      
          projections                                               Yes        Yes    Yes 
          queries with arbitrary return sets                                   Yes    Yes
      
          highly complex queries (like self joins)                                    Yes
      
          some database specific features                                             Yes
      
          performance-optimized queries                                               Yes
      

      更多可以阅读http://tatiyants.com/how-and-when-to-use-various-gorm-querying-options/

      【讨论】:

        猜你喜欢
        • 2014-04-18
        • 2017-03-24
        • 1970-01-01
        • 1970-01-01
        • 2015-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多