我有一个表“mytable”,其中有一列“name”。我希望查询以某个字符串开头或在名称中包含该字符串的所有行,并以以该名称开头的行排在第一位的方式对它们进行排序。是否可以只有一个查询?
我不能使用“联合”,我使用的是 Hibernate,它不受支持。我不想使用视图,因为它们没有被 Hibernate 二级缓存缓存。
在 Oracle 中,您可以执行以下操作:
select *
from myTable mt
where mt.column like '%TargetString%'
order by instr(mt.column, 'TargetString')
如果您使用的是 Hibernate + Oracle,它支持instr
方言中的功能。
我相信其他RDBMS也有类似的功能,可能是Hibernate dialect支持的。
也许这样的事情可以工作?
select nvl(mytable1.name, '') || nvl(mytable2.name, '') as name,
nvl(mytable1.i, '') || nvl(mytable2.i, '') as i from
(select 1 as i, name from mytable where name like ('string%')) mytable1
full outer join
(select 2 as i, name from mytable where name like ('%string%')) mytable2
where (mytable1.name is null or mytable2.name is null)
and mytable1.name != mytable2.name
order by i, name
但我想我会使用以下之一:
编辑:由于您厌恶利用多个标准查询 - 无论出于何种原因 - 我建议阅读Order类。它不会为您提供您想要的。这让你几乎没有选择。
一种选择是利用Hibernate Search。
另一种方法是利用 Hibernate 进行查询,然后再Collections.sort(...)
进行排序。
List<MyObject> lstMyObject = ...;
Collections.sort(lstMyObject, new Comparator<MyObject>() {
@Override
public int compare(MyObject o1, MyObject o2) {
// Assuming 'argument' is passed to this method and defined as 'final'
return o1.getName().startsWith(argument) && o2.getName().startsWith(argument) ? 0 :
o1.getName().startsWith(argument) ? -1 : 1;
}
}
这满足您的要求:1) 使用 Hibernate,2) 不使用多个查询,3) 不使用本机 SQL,4) 不使用视图,5) 不使用“联合”。
我的建议是两个查询,例如:
public List<MyObject> findMyObjects(...) {
Criteria queryStartsWith = sf.getCurrentSession().createCriteria(MyObject.class)
.add(Restrictions.like("myProperty",nameArgument,MatchMode.START))
.addOrder(Order.desc);
Criteria queryLike = sf.getCurrentSession().createCriteria(MyObject.class)
.add(Restrictions.like("myProperty",nameArgument,MatchMode.ANYWHERE))
.addOrder(Order.desc);
List<MyObject> lstMyObject = new ArrayList<MyObject>();
for (Object curObject : queryStartWith.list())
if (curObject instanceOf MyObject)
lstMyObject.add((MyObject) curObject);
for (Object curObject : queryLike.list())
if (curObject instanceOf MyObject)
lstMyObject.add((MyObject) curObject);
return lstMyObject;
}
我不确定 Hibernate 是否会适应您的条件订购。老实说,org.hibernate.criterion.Order 类非常有限。
除了使用本机 SQL,这是我能想到的唯一选择。