【问题标题】:JPA criteriabuilder where statementJPA 标准构建器 where 语句
【发布时间】:2016-01-27 14:02:10
【问题描述】:

我想在我的 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)
        );

但这一切都产生了一个大的 OR 语句

(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

它仍然不是我想要的,我似乎无法让它按照我想要的方式工作。

【问题讨论】:

    标签: java mysql jpa criteria


    【解决方案1】:

    从你明显的第一个问题开始:

    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 ) );
    

    数据库几乎总是代码中较慢的部分,优化器可能会输出相同的运行时或任何一组代码,因此您应该让自己和他人更轻松。此外,这是调试编码问题的久经考验的方法,尤其是当您看到所有这些括号时。

    【讨论】:

    • 非常感谢!您确实为我指明了正确的方向,但我似乎仍然无法让它按照我想要的方式工作。
    • 从简单开始,积累,找出哪里出错了。
    • 我快到了我只是想不通最后一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    • 2020-02-21
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多