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 }

 

转载于:https://www.cnblogs.com/liazu/p/4530502.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值