2014-02-11 1 views
2

эй, я ищу способ поиска текстового шаблона (в jpa) и сортировать результат, сначала весь результат, начинающийся с этой строки, а затем и всех других результатов. я нашел Mysql order by using search string, чтобы получить ответ на MySQLorder-by-use-search-string - JPA

большинство ответов использовать union (который не существует в jpa) и силу для запроса БД или открыть представление для этого. (Заказ от кода не, что хорошее решение, так как мы используем пейджинг, чтобы получить часть результата, как размер результата может быть очень большой)

Одно решение я хотел по ссылке выше является: select * from employee where name like '%ani%' order by locate('ani', name) asc, name asc source

Это кажется мне очень понятным, но я не уверен, как его преобразовать в jpa. Кажется, что объект Order не в состоянии получить местонахождение OUTPUT

любые идеи будут приветствовать

Спасибо!

Alon

EDIT: спасибо за ответ. я получаю то же самое с jpa critiera

Iterator<Order> sortingIter = page.getSort().iterator(); 
ArrayList<javax.persistence.criteria.Order> order = new ArrayList<javax.persistence.criteria.Order>(); 
String fieldName; 
while (sortingIter.hasNext()) { 
     Order sort = sortingIter.next(); 
     fieldName = sort.getProperty(); 
     order.add(sort.getDirection() == Sort.Direction.ASC ? cb 
     .asc(keyword.get(fieldName)) : cb.desc(keyword 
        .get(fieldName))); 
}  

в то время как выше хорошо работает. Я не могу добавить в код следующую строку. Похоже Order объект не любит их

Expression<String> fieldValue = keyword.get(fieldName); 
order.add(cb.locate(fieldValue,key)); 

EDIT 2: пытался order.add (новый javax.persistence.criteria.Order() {

 @Override 
     public javax.persistence.criteria.Order reverse() { 
      // TODO Auto-generated method stub 
      return null; 
     } 

     @Override 
     public boolean isAscending() { 
      // TODO Auto-generated method stub 
      return true; 
     } 

     @Override 
     public Expression<?> getExpression() { 
      // TODO Auto-generated method stub 

      return cb.locate(fieldValue,key); 
     } 
    }); 

JPA не жалуется, но запрос не в порядке

EDIT 3: Обнаружили ошибку!

Ключевое значение, которое я пропустил выше, уже содержит «%» и обе стороны ... поэтому локация не работает должным образом.

сейчас я получаю какое-то странное поведение по некоторым специальным символам: если - например - у меня есть слово Ghurabā, то запрос like %ba% найдет его. но, похоже, что locate(Ghurabā,ba) вернет 0 - что означает pattern was not found in string любая идея, как преодолеть эту проблему?

похоже, что это не только jpa, но и поведение mysql.

SELECT * 
FROM `keywords` 
WHERE name LIKE '%ba%' 
ORDER BY LOCATE( 'ba', name) , name 
LIMIT 0 , 30 

вернет следующий результат

Ghurabā' 
Khuṭabā' 
qabā\ 
Ribāṭ 
ba'urchi (cook) 
Baghdad 
... 

к сведению, что он работает на «обычных английских символов», но есть несоответствие между, как и функция

найти Использование Collcation: utf8_general_ci (получил тот же результат с utf_unicode_ci)

ответ

3

Это не делает никаких жалоб.

String jpql = "select e from Employee e where e.name like '%ani%' order by locate('ani', e.name) asc, e.name asc"; 
TypedQuery<Employee> query2 = em.createQuery(jpql ,Employee.class); 

И это перевод, который делает спящий режим.

Hibernate: выберите employee0_.id в id1_2_, employee0_.address_id в address5_2_, employee0_.DEPT_ID в DEPT6_2_, employee0_.manager_id в manager7_2_, employee0_.name как name2_2_, employee0_.salary в salary3_2_, employee0_. STARTDATE в startDat4_2_ от Работника employee0_ где employee0_.name как '% ани%' заказ на местонахождение ('Эни', employee0_.name) ASC, employee0_.name возрастанию

Используя некоторые данные в качестве ссылки вы упоминаете ,

Employee 10: name: anil, salary: 59000, 
Employee 1: name: anirudha, salary: 55000, 
Employee 5: name: rani, 
Employee 7: name: Stephanie, salary: 54000, 

{индиго, anirudha, рани, ...}

Те же проблемы, используя CriteriQuery решение

Хорошо, у вас есть некоторые моменты, мне для этого =)

Hibernate: выберите employee0_.id как id1_2_, employee0_.address_id as addr ess5_2_, employee0_.DEPT_ID как DEPT6_2_, employee0_.manager_id как manager7_2_, employee0_.name как name2_2_, employee0_.salary as зарплата3_2_, employee0_.startDate как startDat4_2_ от Employee employee0_, где employee0_.name нравится? упорядочить по местонахождению (?, employee0_.name) по возрастанию, employee0_.name по возрастанию

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<Employee> cq = cb.createQuery(Employee.class); 

Root<Employee> root = cq.from(Employee.class); 
cq.where(cb.like(root.<String>get("name"), "%ani%")); 
cq.orderBy(cb.asc(cb.locate(root.<String>get("name"), "ani")), cb.asc(root.get("name"))); 

TypedQuery<Employee> query2 = em.createQuery(cq); 
printList(query2.getResultList()); 

Попробуйте над ним надо работать.

Employee 10: name: anil, salary: 59000, 
Employee 1: name: anirudha, salary: 55000, 
Employee 5: name: rani, 
Employee 7: name: Stephanie, salary: 54000, 

Проверьте это, если вы думаете ? (вопросительный знак) неверен в запросе. http://webdev.apl.jhu.edu/~jcs/ejava-javaee/coursedocs/605-784-site/docs/content/html/jpa-query-criteria-function.html#jpa-query-criteria-function-string-locate

+0

hey @Koitoer благодарит за быстрый ответ. Я редактирую свой вопрос для использования JPA ceriteria – oak