两个“喜欢”的查询组合并订购

时间:2013-04-23 16:32:52

标签: java mysql sql hibernate

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

我不能使用“union”,我正在使用Hibernate并且它不受支持。我宁愿不使用视图,因为它们没有被Hibernate二级缓存缓存。

3 个答案:

答案 0 :(得分:0)

在Oracle中,你可以这样做:

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

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

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

答案 1 :(得分: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个查询。

答案 2 :(得分:-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)不使用'union'。


我的建议是两个查询,喜欢

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之外,这是我能想到的唯一选择。