0

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

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 中缺少一些相当基本的东西。

4

2 回答 2

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.
  }
}
于 2012-05-14T12:23:00.270 回答
0

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

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

def dataSource

[...]    

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

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

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

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

于 2012-05-14T08:13:31.613 回答