Spring Data Jpa 構建動態查詢表達式 使用Oracle特定數據庫函數


  這是一個困惱了我一天的問題,這方面的問題網上的資料也是寥寥無幾,特此記錄。

  如果要在spring data jpa中使用oracle數據庫的特定函數該怎么寫呢?

  本文以使用oracle相似度匹配函數UTL_MATCH.EDIT_DISTANCE_SIMILARITY()為例。該函數作用是匹配兩個字符串的相似度,需要兩個參數。返回值在0到100之間。

  語法引自官網如下:

  UTL_MATCH.EDIT_DISTANCE_SIMILARITY (   s1 IN VARCHAR2,    s2 IN VARCHAR2)    

  RETURN   PLS_INTEGER; 

 例如:SELECT UTL_MATCH.EDIT_DISTANCE_SIMILARITY('shackleford', 'shackelford') FROM DUAL;
  --------------
  returns 82

  在以下的實例中,傳遞給該函數的兩個參數,一個是動態的字段名,一個是個已知的字面量。由於參數類型都需要為Expression類型,動態字段參數還好構建,根據字面量構建Expression就有點不知所措了。

幸好在我的摸索下,發現了有LiteralExpression這個類型,顧名思義字面量表達式。可以作為第二個參數傳遞給函數使用。

  由於是特定數據庫的函數,故我們需要擴展該函數,CriteriaBuilder 接口提供了function()函數供我們使用。

  實例代碼:

 1 List<AppMain>  = appMainDao.findAll(new Specification<AppMain>() {
 2 
 3             @Override
 4             public Predicate toPredicate(Root<AppMain> root,
 5                     CriteriaQuery<?> query, CriteriaBuilder cb) {
 6                 List<Predicate> predicates = new ArrayList<Predicate>();
 7                 predicates.addAll(DesCommonUtils.getPubConditon(root, query, cb));
 8                 
 9                 //本次進件之前
10                 Path<Date> lastCreateDate = root.get("createdTime");
11                 predicates.add(cb.lessThanOrEqualTo(lastCreateDate, thisEntryCreateTime));
12 
13                 //戶籍地址相同 省市全匹配,詳細地址模糊匹配
14                 LiteralExpression<String> regitsterAdressExp = new LiteralExpression<String>(null,
15                         StringUtils.trim2Empty(appCustomer.getRegisterAddress()));
16                 
17                 Expression< Integer> similarityFunc = cb.function("UTL_MATCH.EDIT_DISTANCE_SIMILARITY", 
18                         Integer.class, root.get("appCustomer").get("registerAddress"),regitsterAdressExp);
19                 
20                 predicates.add(cb.and(
21                         cb.equal(root.get("appCustomer").get("registerProvince"), appCustomer.getRegisterProvince()),
22                         cb.equal(root.get("appCustomer").get("registerCity"), appCustomer.getRegisterCity()),
23                         cb.greaterThanOrEqualTo(similarityFunc, 80)
24                         ));
25                 
26                 return cb.and(predicates.toArray(new Predicate[predicates.size()]));
27             }
28         });

  另外在hql中好像也不支持函數名稱中帶有.的sql。若需要在代碼中使用,用@Query注解寫原生sql,可加上nativeQuery屬性。

  例如:    

1 public interface AppCustomerRepository  extends PagingAndSortingRepository<AppCustomer, Long> , JpaSpecificationExecutor<AppCustomer>{
2     
3     @Query(value = "select UTL_MATCH.EDIT_DISTANCE_SIMILARITY('a','a')  from DUAL ", nativeQuery = true)
4     Double getSimilarity();
5 
6 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM