Jpa-Spec oracle函数bitand,instr等扩展

Posted hankuikui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jpa-Spec oracle函数bitand,instr等扩展相关的知识,希望对你有一定的参考价值。

jpa-spec github: https://github.com/wenhao/jpa-spec

使用这个框架可以简化我们拼条件的复杂度,如下代码:

public Page<Person> findAll(SearchRequest request) 
    Specification<Person> specification = Specifications.<Person>and()
            .eq(StringUtils.isNotBlank(request.getName()), "name", request.getName())
            .gt("age", 18)
            .between("birthday", new Date(), new Date())
            .like("nickName", "%og%")
            .build();

    Sort sort = Sorts.builder()
        .desc(StringUtils.isNotBlank(request.getName()), "name")
        .asc("birthday")
        .build();

    return personRepository.findAll(specification, new PageRequest(0, 15, sort));

这是一个分页+排序的查询。

但如果我们使用的是数据库特定的函数,这个框架提供的方法就不够用了,需要我们扩展:

我们使用的是oracle数据库,它的函数如bitand, instr就需要我们扩展:

jpa-spec bitand扩展:

/**
 * Oracle bitand函数 计算扣款规则rulebit
 *
 * @author :hkk
 * @date :Created in 2019/7/24 10:34
 */
public class BitandSpecification<T> extends AbstractSpecification<T> 
    private String property;
    private List<BigDecimal> values;

    public BitandSpecification(String property, List<BigDecimal> values) 
        this.property = property;
        this.values = values;
    

    @Override
    public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) 

        BigDecimal sum = values.stream().reduce(BigDecimal::add).get();

        LiteralExpression<BigDecimal> literalExpression = new LiteralExpression<>(null, sum);

        Expression<BigDecimal> ruleBit = cb.function("bitand",
                BigDecimal.class,
                root.get(property), literalExpression);

        return cb.greaterThan(ruleBit, BigDecimal.ZERO);

    

jpa-spec instr扩展:

/**
 * Oracle instr函数 计算扣款规则rulebit
 *
 * @author :hkk
 * @date :Created in 2019/7/24 10:34
 */
public class IntstrSpecification<T> extends AbstractSpecification<T> 
    private String property;
    private String value;

    public IntstrSpecification(String property, String value) 
        this.property = property;
        this.value = value;
    

    @Override
    public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) 

        LiteralExpression literalExpression = new LiteralExpression(null, value);

        Expression<BigDecimal> instr = cb.function("instr",
                BigDecimal.class,
                root.get(property), literalExpression);

        return cb.greaterThan(instr, BigDecimal.ZERO);

    

然后,我们再修改PredicateBuilder类:增加两个方法:

   /**
     *  oracle 函数bitand
     * @param property
     * @param var
     * @return
     */
    public PredicateBuilder<T> bitand(String property, List var) 

        if (!CollectionUtils.isEmpty(var)) 
            this.predicate(true, new BitandSpecification(property, var));
        
        return this;
    

    /**
     *  oracle 函数instr
     * @param property
     * @param var
     * @return
     */
    public PredicateBuilder<T> instr(String property, String var) 

        if (StringUtils.isNotBlank(var)) 
            this.predicate(true, new IntstrSpecification(property, var));
        
        return this;
    

 

同时我们增加了一些方法,传入参数为空时的判断,减少开发人员的代码量:

/**
     * value不为空时 in
     * @param property
     * @param values
     * @return
     */
    public PredicateBuilder<T> inWhereHasValues(String property, List values) 
        if (!CollectionUtils.isEmpty(values)) 
            this.in(property, values);
        
        return this;
    

    /**
     * 当values为空是 is null
     * 当values不为空时 in
     * @param property
     * @param values
     * @return
     */
    public PredicateBuilder<T> inAndNull(String property,  List values) 
        if (CollectionUtils.isEmpty(values)) 
            return this.eq(property, values);

        
        return in(property,values);
    

public PredicateBuilder<T> eqWhereHasValue(String property, Object... values) 
        if (values == null) 
            return this;
        
        if (values.length == 1) 
            if (values[0] == null) 
                return this;
            
            if (StringUtils.isBlank(String.valueOf(values[0]))) 
                return this;
            

        

        return eq(true, property, values);
    

 

希望对刚入门jps的同学有所帮助,也算是我们对社区的回馈:)

 

以上是关于Jpa-Spec oracle函数bitand,instr等扩展的主要内容,如果未能解决你的问题,请参考以下文章

oracle 函数 bitand 与 decode

oracle 某一字段取反

Oracle位函数及其实例

Oracle常用函数

Spring Data Jpa之高级查询(jpa-spec插件)

ORACLE隐藏参数查看及修改