1

我有一个表“mytable”,其中有一列“name”。我希望查询以某个字符串开头或在名称中包含该字符串的所有行,并以以该名称开头的行排在第一位的方式对它们进行排序。是否可以只有一个查询?

我不能使用“联合”,我使用的是 Hibernate,它不受支持。我不想使用视图,因为它们没有被 Hibernate 二级缓存缓存。

4

3 回答 3

0

在 Oracle 中,您可以执行以下操作:

select *
  from myTable mt
 where mt.column like '%TargetString%'
 order by instr(mt.column, 'TargetString')

如果您使用的是 Hibernate + Oracle,它支持instr方言中的功能。

我相信其他RDBMS也有类似的功能,可能是Hibernate dialect支持的。

于 2013-04-23T17:01:27.530 回答
0

也许这样的事情可以工作?

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

但我想我会使用以下之一:

  • 这个查询的一个简单的联合查询
  • 而是在 Java 中进行排序,并将其作为 2 个查询进行。
于 2013-04-23T17:07:47.140 回答
-1

编辑:由于您厌恶利用多个标准查询 - 无论出于何种原因 - 我建议阅读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,这是我能想到的唯一选择。

于 2013-04-23T17:28:51.907 回答