如何根据特定的顺序排列hibernate的结果 [英] How to order result of hibernate based on a specific order

查看:168
本文介绍了如何根据特定的顺序排列hibernate的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要发送一个查询来检索具有特定字符组的值,如下所示:



可以说我对'XX'感兴趣,所以它应该搜索对于其值为'XX'或具有'XX'(空间XX)的任何字段。例如 XXCDEF PD XXRF CMKJIEK XX 是否有效结果。

我有以下查询,
返回正确的结果,但我需要对它们进行排序
,它首先以 XX 开头,然后返回其他结果。如下所示:

  XXABCD 
XXPLER
XXRFKF
AB XXAB
CD XXCD
ZZ XXOI
POLO XX

代码

  Criteria criteria = session.createCriteria(Name.class,name)
.add(Restrictions.disjunction()
.add(Restrictions.ilike(name.fname,fname +%))
.add(Restrictions.ilike(name.fname,%++ fname + %))

.setProjection(Projections.property(name.fname)。as(fname));
列表< String> names =(List< String>)criteria.list();


解决方案

>:

pre $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $'$'
order by(case upper(fname)like:fnameStart then 1 else 2 end),fname

query.setParameter(fnameStart,XX%);
query.setParameter(fnameMiddle,%XX%);

符合标准

使用 Criteria 它更加棘手。首先,你必须使用顺序子句中的原生SQL。其次,你必须绑定变量。

  public class FirstNameOrder extends Order {
public FirstNameOrder(){
super(,true);
}
$ b $ @Override
public String toSqlString(Criteria criteria,CriteriaQuery criteriaQuery)throws HibernateException {
return'case upper(FIRST_NAME)like?then 1 else 2结束;


$ / code>

表达式语法和 upper 函数名称应根据数据库进行更改(当然,如果名称不同,则使用列名称)。

这很容易将它添加到 Criteria 中,但没有API绑定参数。



我试图欺骗Hibernate通过将一个未使用的变量传递给自定义sql限制,以便通过子句有效地用于顺序中的变量:

  Criteria criteria = session.createCriteria(Name.class,name)
.add(Restrictions.disjunction()
.add(Restrictions.ilike (name.fname,fname +%))
.add(Restrictions.ilike(name.fname,%++ fname +%)))
.setProjection(Projections.property(name.fname)。as(fname))
.add(Restrictions.sqlRestriction(1 = 1,fname +%,StringType.INSTANCE))
.addOrder(new FirstNameOrder())
.addOrder(Order.asc(fname));

,它可以正常工作。



显然,不建议使用此解决方案,我建议使用JPQL进行此查询。


I need to send a query to retrieve values that has a specific group of characters as following:

Lets say I am interested in 'XX' so it should search for any field that its value starts with 'XX' or has ' XX' (space XX). For example XXCDEF, PD XXRF and CMKJIEK XX are valid results.

I have following query that returns the correct results but I need to sort them in a way that it first return those with XX at the beginning then other results. As following:

XXABCD
XXPLER
XXRFKF
AB XXAB
CD XXCD
ZZ XXOI
POLO XX

Code

Criteria criteria = session.createCriteria(Name.class, "name")
                .add(Restrictions.disjunction()
                     .add(Restrictions.ilike("name.fname", fname + "%"))
                     .add(Restrictions.ilike("name.fname", "%" + " " + fname + "%"))
                    )
                .setProjection(Projections.property("name.fname").as("fname"));
        List<String> names = (List<String>) criteria.list();

解决方案

With JPQL (HQL):

select fname from Name
where upper(fname) like :fnameStart or upper(fname) like :fnameMiddle
order by (case when upper(fname) like :fnameStart then 1 else 2 end), fname

query.setParameter("fnameStart", "XX%");
query.setParameter("fnameMiddle", "% XX%");

With Criteria

With Criteria it's much trickier. Firstly, you have to resort to native SQL in the order clause. Secondly, you have to bind the variable.

public class FirstNameOrder extends Order {
    public FirstNameOrder() {
        super("", true);
    }

    @Override
    public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
        return "case when upper(FIRST_NAME) like ? then 1 else 2 end";
    }
}

The case expression syntax and the upper function name should be changed in accordance with your database (and the column name if it's different, of course).

It is easy to add this to the Criteria, but there is no API to bind the parameter.

I tried to trick Hibernate by passing in an unused variable to the custom sql restriction so that it is effectively used for the variable in the order by clause:

Criteria criteria = session.createCriteria(Name.class, "name")
   .add(Restrictions.disjunction()
      .add(Restrictions.ilike("name.fname", fname + "%"))
      .add(Restrictions.ilike("name.fname", "%" + " " + fname + "%")))
   .setProjection(Projections.property("name.fname").as("fname"))
   .add(Restrictions.sqlRestriction("1 = 1", fname + "%", StringType.INSTANCE))
   .addOrder(new FirstNameOrder())
   .addOrder(Order.asc("fname"));

and it works fine.

Obviously, this solution is not recommended and I suggest using JPQL for this query.

这篇关于如何根据特定的顺序排列hibernate的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆