How to order result of hibernate based on a specific order

前端 未结 6 1918
别那么骄傲
别那么骄傲 2021-01-07 19:15

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

相关标签:
6条回答
  • 2021-01-07 19:52

    Stupid but it may work for your case.

    Since you got your correct result you can just reconstruct your results as follows:

    1. pick up all results starting with XX you put them into a list L1 and do the normal sort like Collections.sort(L1);
    2. for all other results, do the same like Collections.sort(L2)as list of L2
    3. At last , put them together

      List newList = new ArrayList(L1);

      newList.addAll(L2);

    Please note. Collections.sort are following the natural ordering of its elements.

    0 讨论(0)
  • 2021-01-07 20:08

    You can use Predicates in criteria... something like this:

    public List<Name> findByParameter(String key, String value, String orderKey)
    
                CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
                CriteriaQuery<Name> criteria = builder.createQuery(this.getClazz());
                Root<Name> root = criteria.from(Name.getClass());
                criteria.select(root);
                List<Predicate> predicates = new ArrayList<Predicate>();
                predicates.add(builder.equal(root.get(key), value));
                criteria.where(predicates.toArray(new Predicate[predicates.size()]));
                if (orderKey!=null  && !orderKey.isEmpty()) {
                    criteria.orderBy(builder.asc(root.get(orderKey)));
                }
                result = this.entityManager.createQuery(criteria).getResultList();
    
            return result;
    }
    
    0 讨论(0)
  • 2021-01-07 20:09

    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.

    0 讨论(0)
  • 2021-01-07 20:10

    Hibernate supports Order: http://docs.jboss.org/hibernate/orm/4.2/devguide/en-US/html/ch11.html#ql-ordering Because of the special criteria, I think you have to custom the Order in Hibernate. This link may help: http://blog.tremend.ro/2008/06/10/how-to-order-by-a-custom-sql-formulaexpression-when-using-hibernate-criteria-api/

    0 讨论(0)
  • 2021-01-07 20:11

    If you don't want to sort the result in memory,you can modify your criteria,I'll show you the SQL

    select * from table where fname like 'XX%' order by fname
    union all
    select * from table where fname like '% XX%' order by fname
    union all
    select * from table where fname like '% XX' order by fname
    

    the result will be your order and alphabetical and then apply your filter.

    0 讨论(0)
  • 2021-01-07 20:12

    Run two selects, one filtered for all the strings starting with 'XX', the second filtered for the others.

    0 讨论(0)
提交回复
热议问题