【问题标题】:Avoiding subqueries in HQL using Grails使用 Grails 避免 HQL 中的子查询
【发布时间】:2012-05-13 19:57:30
【问题描述】:

我有两个对象,一个房间类型和一个预订。简化为:

class Room {
  String description
  int quantity
}

class Reservation {
  String who
  Room room
}

我想查询所有房间以及每种类型的可用房间数量。在 SQL 中,这是我想要的:

select id, quantity, occupied, quantity-coalesce(occupied, 0) as available
from room left join(select room_id, count(room_id) as occupied from reservation) 
on id = room_id;

我无处可寻,想知道如何用 HQL 做到这一点。

我会很感激任何指点,因为我似乎在 HQL 或 GORM 中遗漏了一些相当基本的东西。

【问题讨论】:

    标签: grails hql grails-orm


    【解决方案1】:

    这里的问题是您试图表示不是您的域类的字段,例如availableoccupied。试图让 HQL\GORM 做到这一点可能有点令人沮丧,但并非不可能。我认为您在这里有几个选择...

    1.) 构建您的域类,以便更易于使用。也许您的 Room 需要通过映射表了解它的 Reservations,或者,也许编写您想要的代码看起来然后调整设计。

    例如。也许你希望你的代码看起来像这样......

    RoomReservation.queryAllByRoomAndDateBetween(room, arrivalDate, departureDate);  
    

    那你就这样实现吧……

        class RoomReservation{
            ...
            def queryAllByRoomAndDateBetween(def room, Date arrivalDate, Date departureDate){
               return RoomReservation.withCriteria {
                 eq('room', room)
                 and {
                   between('departureDate', arrivalDate, departureDate)
                 }
            }
        }
    

    2.) 我的第二个想法是...... 可以将数据库用于它的好处。有时在代码中使用 sql 只是做某事的最有效方法。 只需适度进行,并保持集中化和单元测试。我不建议您使用这种方法,因为您的查询并不复杂,但它是一种选择。我将存储过程用于查询数百万个对象以获取摘要数据的“仪表板视图”之类的内容。

    class Room{
        ...
      def queryReservations(){
          def sql = new Sql(dataSoruce);
          return sql.call("{call GetReservations(?)}", [this.id]) //<-- stored procedure.
      }
    }
    

    【讨论】:

      【解决方案2】:

      我不确定如何用 HQL 中的子查询来描述左连接。在任何情况下,如果 HQL 不够表达,您也可以轻松地在 grails 中执行原始 SQL:

      在您的服务中,注入数据源并创建一个 groovy.sql.Sql 实例

      def dataSource
      
      [...]    
      
      def sql= new Sql(dataSource)
      sql.eachRow("...."){row->
          [...]
      }
      

      我知道当人们在你提出问题时试图光顾你而不是回答你的问题或只是闭嘴时,这很烦人,但在我看来,这个问题非常复杂,我会创建一个我的数据结构中这个数字的概念,可能是一个与房间相关联的可用性表,它不仅可以计算数量,还可以计算占用的值。

      这不是每次需要时都计算它。

      只是我的 $.02,如果它惹恼了你,请忽略它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-08
        • 2014-12-15
        • 1970-01-01
        相关资源
        最近更新 更多