我想在CriteriaQuery中实现以下where语句。

  (Event.time >= NOW()
     OR (Event.time >= '$clubHours' && (`EventSelectType`.`type`='cafe' || `EventSelectType`.`type`='DJ'))
     OR (Event.endtime >= NOW() && (`EventSelectType`.`type`='festival' OR `EventSelectType`.`type`='dj' OR `EventSelectType`.`type`='cafe')))

我试过了以下几点:;
eQr.where(
        cB.or(
            cB.or(
                    cB.greaterThanOrEqualTo(eventRoot.<Date>get("time"), curDate)
                ),
            cB.or(
                    cB.and(
                    cB.greaterThanOrEqualTo(eventRoot.<Date>get("time"), cal.getTime())
                    ),
                        cB.or(
                                cB.equal(eventType.<String>get("type"), "cafe"),
                                cB.equal(eventType.<String>get("type"), "DJ")
                                )
                ),
            cB.or(
                    cB.and(
                    cB.greaterThanOrEqualTo(eventRoot.<Date>get("endtime"), curDate)
                    ),
                        cB.or(
                                cB.equal(eventType.<String>get("type"), "festival"),
                                cB.equal(eventType.<String>get("type"), "DJ"),
                                cB.equal(eventType.<String>get("type"), "cafe")
                                )
                )
        ),
        cB.equal(eventRoot.<Integer>get("id"), eventID),
        cB.equal(eventRoot.<Integer>get("active"), 1)
        );

但所有这些都是一个大或声明
(event0_.time>=? or event0_.time>=? or eventselec13_.type=? or eventselec13_.type=? or event0_.endtime>=? or eventselec13_.type=? or eventselec13_.type=? or eventselec13_.type=?)

我怎样才能得到我想要的结果呢?
编辑
我现在有这个
Predicate eventTypeIscafeORDJ = cB.or(
        cB.equal(eventType.<String>get("type"), "cafe"),
        cB.equal(eventType.<String>get("type"), "DJ")
    );
Predicate eventTypeIsFestivalDJORCafe = cB.or(
        cB.equal(eventType.<String>get("type"), "cafe"),
        cB.equal(eventType.<String>get("type"), "DJ"),
        cB.equal(eventType.<String>get("type"), "festival")
        );

    Predicate timeGreaterOrEqualTo = cB.greaterThanOrEqualTo(eventRoot.<Date>get("time"), cal.getTime());
    Predicate endTimeGreaterOrEqualTo = cB.greaterThanOrEqualTo(eventRoot.<Date>get("endtime"), curDate);
    Predicate equalToId = cB.equal(eventRoot.<Integer>get("id"), eventID);

    eQr.where(timeGreaterOrEqualTo, cB.or( cB.and( timeGreaterOrEqualTo, eventTypeIscafeORDJ ), cB.and(endTimeGreaterOrEqualTo, eventTypeIsFestivalDJORCafe )), equalToId);

哪些输出
where event0_.time>=? and (event0_.time>=? and (eventselec13_.type=? or eventselec13_.type=?) or event0_.endtime>=? and (eventselec13_.type=? or eventselec13_.type=? or eventselec13_.type=?)) and event0_.id=633188

但必须是
where (event0_.time>=? OR (event0_.time>=? and (eventselec13_.type=? or eventselec13_.type=?)) or (event0_.endtime>=? and (eventselec13_.type=? or eventselec13_.type=? or eventselec13_.type=?))) and event0_.id=633188

它仍然不完全是我想要的,我似乎无法得到它的工作方式,我希望它。

最佳答案

从你显而易见的第一个问题开始:

Event.time >= '$clubHours' && (`EventSelectType`.`type`='cafe' || `EventSelectType`.`type`='DJ'))

它应该被构造为
cB.and(
    cB.greaterThanOrEqualTo(eventRoot.<Date>get("time"), cal.getTime()),
    cB.or(
        cB.equal(eventType.<String>get("type"), "cafe"),
        cB.equal(eventType.<String>get("type"), "DJ")
    )
), ...

取而代之的是:
cB.and(
    cB.greaterThanOrEqualTo(eventRoot.<Date>get("time"), cal.getTime())
),
cB.or(
    cB.equal(eventType.<String>get("type"), "cafe"),
    cB.equal(eventType.<String>get("type"), "DJ")
)

因此,基本上,您需要确保查看括号而不是缩进,以了解您的代码在做什么。另外,最好分步构造这个谓词,这样代码更容易阅读和理解。例如。:
Predicate eventTypeIscafeORDJ = cB.or(
    cB.equal(eventType.<String>get("type"), "cafe"),
    cB.equal(eventType.<String>get("type"), "DJ")
);
Predicate timeGreaterOrEqualTo = cB.greaterThanOrEqualTo(eventRoot.<Date>get("time"), cal.getTime());
eQr.where( cB.and( timeGreaterOrEqualTo, eventTypeIscafeORDJ ) );

数据库几乎总是代码中速度较慢的部分,优化器可能会生成相同的运行时或任意一组代码,因此您应该使自己和其他人更轻松。此外,这是调试编码问题的经过时间考验的方法,特别是当您看到所有这些paren时。

09-10 09:32