【问题标题】:JPA - Ensure that no reservation has conflict with required reservationJPA - 确保没有预留与所需预留发生冲突
【发布时间】:2020-12-11 18:20:39
【问题描述】:

我正在为一个项目构建一个简单的可出租的预订应用程序。如果没有其他与所需预订相冲突的预订,用户可以预订房屋。
我有两个实体类 - Rentable 和 Reservation
预订与可出租和 2 个感兴趣的领域具有 @ManyToOne 关系——reserveFrom 和 reserveUntil。
问题如下:
因为我希望提供分页功能,所以我需要一种返回响应块的方法,因此应用程序级别的解决方案(即通过将所有内容加载到内存中进行过滤等)非常昂贵。
用户应该能够提供两个日期(从、到),然后返回大量可用的可出租物品。

有关如何实现此查询的任何指南?我可以看到以下情况:如果存在属于可出租的某些其他预留 r2,则特定预留 r1 的可出租不可用
r2.reserveFrom r2.reserveFrom r1.reserveFrom

目前我想到的一个基线查询如下(输入:f (from), t (to))

SELECT DISTINCT rentable
FROM Rentable rentable JOIN Reservation reservation
WHERE NOT (f BETWEEN reservation.reserveFrom AND reservation.reserveUntil
OR t BETWEEN reservation.reserveFrom AND reservation.reserveUntil
OR (f > reservation.reserveFrom AND t < reservation.reserveUntil))

这样做的问题是,仅仅因为一行通过了过滤器,并不意味着应该返回可出租的(其他一些行可能会取消它的资格)。
我觉得必须涉及一些 EXISTS 子句。任何帮助表示赞赏。

【问题讨论】:

标签: sql postgresql jpa jpql


【解决方案1】:

您对存在的期望是正确的,更具体地说,不存在。看起来您已经确定了重叠覆盖范围,没有必要,Postgres 已经为此内置了运算符。而不是使用单个日期将表日期和参数日期组合到 DATERANGE 中,然后应用 OVERLAP 运算符 (&&)。结果将是一个确实有重叠的列表。这进入了 NOT EXISTS 谓词。

create or replace 
function available_rentables(from_date_in date, to_date_in date)
  returns setof rentable
  language sql
as $$
with request (parm_range) as 
     ( select  daterange ( from_date_in
                         , to_date_in
                         , '[]'
                         )    
     )   
select *
  from rentable  ren
 where not exists 
       (select null 
          from reservation res
          join request   
            on daterange(res.from_date, res.to_date) && parm_range
       );
$$; 

以上为您提供了在指定的从日期到日期范围内可用的可出租房屋的列表。以上假设范围包括两个端点。此外,根据总体使用情况,您可以将 from_date、to_date 列保留存储为单个日期范围。
正如@a_horse_with_no_name 所暗示的那样,排他约束将是数据库级别的良好保险。

【讨论】:

    猜你喜欢
    • 2019-09-27
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 2017-04-13
    相关资源
    最近更新 更多