我有两个对象,房间类型和预订。简化它们是:
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中缺少一些相当基本的东西。
答案 0 :(得分:1)
此处的问题是您尝试表示不属于您的域类的字段,例如available
和occupied
。试图让HQL \ GORM执行此操作可能有点令人沮丧,但并非不可能。我想你在这里有几个选择......
1。)构建您的域类,以便更容易使用。也许您的房间需要通过映射表了解它的预订,或者或许写下您想要的代码看起来然后调整设计。
例如。也许你希望你的代码看起来像这样......
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.
}
}
答案 1 :(得分:0)
我不确定如何用HQL中的子查询描述左连接。在任何情况下,如果HQL表达不够,你也可以轻松地在grails中执行原始SQL:
在您的服务中,注入dataSource并创建一个groovy.sql.Sql实例
def dataSource
[...]
def sql= new Sql(dataSource)
sql.eachRow("...."){row->
[...]
}
我知道,当你提出问题时,当人们试图光顾你的思维方式而不是回答你的问题或只是闭嘴时,我觉得非常讨厌,但在我看来,这个查询非常复杂,我会创建一个在我的数据结构中这个数字的概念,也许是与房间相关联的可用性表,它不仅可以计算数量,还可以计算占用值。
这不是每次需要时计算它。
只要我的$ .02如果它让你烦恼就忽略它。