我对hibernate相当新,目前正在使用标准触发查询。
我想要实现的是,在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%')
这将在first或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)
));
}
}
}
哪个产生这个查询,这几乎是我想要的。我只想让“AND”成为“OR”。所以:
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 ?
)
答案 0 :(得分: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);