2014-02-11 76 views
2

嘿,我正在尋找方式來搜索文本模式(以jpa)和排序結果,首先所有結果開始與此字符串,然後所有其他結果。 我發現Mysql order by using search string獲得MySQL的order by - 使用搜索字符串 - JPA

答案大部分的答案使用union(其中不存在jpa)和力來查詢數據庫或打開一個視圖。 (從代碼排序,良好的解決方案,因爲我們使用分頁得到的結果作爲結果的大小可真夠大的一部分)

一個解決方案,我從上面的鏈接喜歡的是: select * from employee where name like '%ani%' order by locate('ani', name) asc, name asc source

這在我看來很清楚,但我不知道如何將其轉換爲jpa。好像Order對象是不是能夠得到定位輸出

任何想法將受到歡迎

謝謝!

阿龍

編輯: 感謝答覆。我試圖達到與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)); 

編輯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不會抱怨,但查詢沒有得到正確的訂單

編輯3: 發現我的錯誤!

我上面傳遞的關鍵值已經包含「%」和雙方...所以找到沒有正常工作。

現在我在某些特殊字符上出現了一些奇怪的行爲:if - 例如 - 我有字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 
... 

注意其工作「正規英文字符」但等與定位功能

之間的不匹配使用Collcationutf8_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 LIKE '%ANI%' ORDER BY定位( 'ANI', employee0_.name)ASC,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作爲addr ess5_2_,employee0_.DEPT_ID as DEPT6_2_,employee0_.manager_id as manager7_2_,employee0_.name as name2_2_,employee0_.salary as salary3_2_,employee0_.startDate as startDat4_2_ from Employee employee0_ where employee0_.name like? order by locate(?, employee0_.name)asc,employee0_.name asc

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

嘿@Koitoer感謝您的快速回復。我編輯我的問題使用JPA ceriteria – oak