【问题标题】:Hibernate criteria with variable amount of OR LIKE clauses具有可变数量的 OR LIKE 子句的休眠标准
【发布时间】:2013-10-13 05:49:14
【问题描述】:

我对休眠相当陌生,目前正在努力使用标准触发查询。

我想要实现的是,在 first 或 lastname 列中选择包含特定字符串的所有记录。

这就是我所拥有的。它应该给出一个更好的主意。

Session session = HibernateUtil.openSession();
    Criteria criteria = session.createCriteria(Contact.class);

    if(keywords != null) {
        for(String keyword : keywords) {
            if(keyword != null && keyword.length() > 0) {
                criteria.add(Restrictions.like("firstName", keyword, MatchMode.ANYWHERE));
                criteria.add(Restrictions.or(Restrictions.like("lastName", keyword, MatchMode.ANYWHERE), null));
            }
        }
    }

    searchMatches = criteria.list();

所以最后查询应该是这样的:

SELECT * FROM contacts WHERE(firstname LIKE '%oe% OR lastname LIKE '%oe%'),如果给出多个关键字,类似:

SELECT * FROM contacts WHERE (firstname LIKE '%oe% OR lastname LIKE '%oe%') OR (firstname LIKE '%roo% OR lastname LIKE '%roo%')

这将选择在 firstname 或 lastname 列中包含“oe”的记录。 当criteria.list(); 时我怎么会遇到代码崩溃?正在运行。

这是堆栈跟踪。我不知道我做错了什么。

Caused by: java.lang.NullPointerException
at org.hibernate.criterion.LogicalExpression.toSqlString(LogicalExpression.java:60)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:419)
at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:123)
at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:92)
at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:93)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1464)
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374)
at com.joey.wishlist.dao.impl.ContactDAOImpl.searchContacts(ContactDAOImpl.java:34)
at com.joey.wishlist.services.impl.ContactServiceImpl.searchContacts(ContactServiceImpl.java:22)
at com.joey.wishlist.presenters.ContactSearchPresenter.search(ContactSearchPresenter.java:75)

编辑:我更近了一步。

我修正了错误。该错误是由故障或故障引起的。

现在的代码如下所示:

        if(keywords != null) {
        for(String keyword : keywords) {
            if(keyword != null && keyword.length() > 0) {
                criteria.add(
                        Restrictions.or(
                            Restrictions.like("lastName", keyword, MatchMode.ANYWHERE), 
                            Restrictions.like("firstName", keyword, MatchMode.ANYWHERE)
                        ));
            }
        }
    }

这会产生这个查询,这几乎是我想要的。我只希望“与”为“或”。所以:

Hibernate: 
/* criteria query */ select
    this_.id as id0_0_,
    this_.firstname as firstname0_0_,
    this_.lastname as lastname0_0_ 
from
    contactmanager this_ 
where
    (
        this_.lastname like ? 
        or this_.firstname like ?
    ) 
    and (
        this_.lastname like ? 
        or this_.firstname like ?
    )

我想成为:

Hibernate: 
/* criteria query */ select
    this_.id as id0_0_,
    this_.firstname as firstname0_0_,
    this_.lastname as lastname0_0_ 
from
    contactmanager this_ 
where
    (
        this_.lastname like ? 
        or this_.firstname like ?
    ) 
    or ( //Notice difference here
        this_.lastname like ? 
        or this_.firstname like ?
    )

【问题讨论】:

    标签: java mysql hibernate criteria


    【解决方案1】:

    每次您拨打criteria.add 时,它都会在您的声明中添加一个and。 您要创建析取的内容:

    Disjunction matchDisjunction = Restrictions.disjunction()
    for(String keyword : keywords) {
                if(keyword != null && keyword.length() > 0) {
                    matchDisjunction.add(
                            Restrictions.or(
                                Restrictions.like("lastName", keyword, MatchMode.ANYWHERE), 
                                Restrictions.like("firstName", keyword, MatchMode.ANYWHERE)
                            ));
                }
            }
    criteria.add(matchDisjunction);
    

    或者简单地说:

    Disjunction matchDisjunction = Restrictions.disjunction()
    for(String keyword : keywords) {
                if(keyword != null && keyword.length() > 0) {
                    matchDisjunction.add( Restrictions.like("lastName", keyword, MatchMode.ANYWHERE) );
                    matchDisjunction.add( Restrictions.like("firstName", keyword, MatchMode.ANYWHERE) );
                }
            }
    criteria.add(matchDisjunction);
    

    【讨论】:

    • 非常感谢您的宝贵时间。我没有时间测试它。我今晚会。敬请期待。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 2014-06-24
    • 2011-10-23
    相关资源
    最近更新 更多