【问题标题】:negating an expression in ebean否定 ebean 中的表达式
【发布时间】:2016-03-05 10:31:55
【问题描述】:

我正在使用带有 ebean 的播放框架 2.3.4。我的数据库中有这两个表:

@Entity
public class Device extends Model {

    @Id
    public Long id;

    @OneToMany(mappedBy = "device")
    public List<DeviceInactivePeriod> inactivePeriods = new ArrayList<DeviceInactivePeriod>();

    ...
}

@Entity
public class DeviceInactivePeriod extends Model {

    @Id
    public Long id;

    @Constraints.Required
    @Formats.DateTime(pattern = "dd-MM-yyyy HH:mm")
    public Date start;

    @Formats.DateTime(pattern = "dd-MM-yyyy HH:mm")
    public Date end;

    @ManyToOne
    public Device device;

    ...

}

DeviceInactivePeriod 对象想象为一个时间段,其中设备处于非活动状态。 DEVICE 包含它们的列表。

现在我想查询所有设备,在特定时刻(例如现在)没有DeviceInactivePeriod(这意味着设备处于活动状态)

我尝试了很多很多东西,但都没有成功。我有这个问题:

    Date now = new Date();
    return
            find.where().
                    and(
                        Expr.le("inactivePeriods.start", now),
                        Expr.ge("inactivePeriods.end", now)
                    )
                    .orderBy(sorting + " " + order)
                    .findPagingList(Global.PAGE_SIZE_DEVICES)
                    .setFetchAhead(false)
                    .getPage(page);

准确返回所有处于非活动状态的设备。 (与我想要的相反)。不幸的是,否定这个查询不会返回我期望的结果。也许我否定错了?这是我的工作:

    Date now = new Date();
    return
            find.where().
                    .not(Expr.and(
                        Expr.le("inactivePeriods.start", now),
                        Expr.ge("inactivePeriods.end", now)
                    ))
                    .orderBy(sorting + " " + order)
                    .findPagingList(Global.PAGE_SIZE_DEVICES)
                    .setFetchAhead(false)
                    .getPage(page);

谁能给我一个解决方案?或者任何人都可以提出原始 SQL 解决方案吗?

更新

这是生成的 SQL:

[debug] c.j.b.PreparedStatementHandle - select distinct t0.id c0, [...] from device t0 join device_inactive_period u1 on u1.device_id = t0.id where not ((u1.start <= 2016-03-06 11:35:15.048 and u1.end >= 2016-03-06 11:35:15.048 ) ) order by t0.exp_date desc limit 11

问题是对于每个DeviceInactiveDevicePeriod 中可能有 0 到多行,如果 ((u1.start &lt;= 2016-03-06 11:35:15.048 and u1.end &gt;= 2016-03-06 11:35:15.048 ) ),SQL DBMS 会检查每一行。对于每个设备,如果只有 1 行在此条件下返回 true,则将返回整个设备。另一个问题是,如果设备没有InactiveDevicePeriod 条目,则不会返回。

在java中它相当于这种代码的和平(我认为!)(在Device.java中):

public boolean isActive_at_Wrong(Date date){
    for (DeviceInactivePeriod inactivePeriod : inactivePeriods) {
        if ( (inactivePeriod.start.before(date) || inactivePeriod.start.equals(date)) && inactivePeriod.end.after(date)){
            return false;
        } else {
            return true;
        }
    }
    return false;
}

但我想要的是这个(在 Device.java 中):

public boolean isAactive_at_Correct(Date date){
    boolean active = true;
    for (DeviceInactivePeriod inactivePeriod : inactivePeriods) {
        if ( (inactivePeriod.start.before(date) || inactivePeriod.start.equals(date)) && inactivePeriod.end.after(date)){
            active = false;
        }
    }

    return active;
}

【问题讨论】:

  • 包括生成的 SQL ...然后查看 where 子句并描述它需要什么,然后将其与您的问题一起发布。
  • 我刚刚用更多信息更新了这个问题@RobBygrave

标签: sql playframework playframework-2.3 ebean


【解决方案1】:

我没有测试过,但我认为您可以改用between 子句:

Date now = new Date();
return find
    .where()
    .not(Expr.between("inactivePeriods.start", "inactivePeriods.end", now))
    .orderBy(sorting + " " + order)
    .findPagingList(Global.PAGE_SIZE_DEVICES)
    .setFetchAhead(false)
    .getPage(page);

【讨论】:

  • 谢谢,但它仍然没有返回我想要的。 :-(
  • 这种情况下返回什么?
  • 我有 4 个示例设备,2 个当前处于活动状态,另外 2 个当前处于不活动状态。您的代码返回 1 个活动和其中一个活动。不应该返回的 Inactive 具有以下 DeviceInactivePeriod 对象:1)开始:9.2.2016 结束:1.3.2016 2)开始:3.3.2016 结束:6.3.2016
  • 这是你代码生成的SQL(我自己加了[...][debug] c.j.b.PreparedStatementHandle - select distinct t0.id c0, [...] from device t0 join device_inactive_period u1 on u1.device_id = t0.id where not ( 2016-03-06 11:24:25.702 between u1.start and u1.end) order by t0.exp_date desc limit 11
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-17
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2011-05-15
  • 2021-10-02
相关资源
最近更新 更多