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的同学有所帮助,也算是我们对社区的回馈:)

猜你喜欢

转载自www.cnblogs.com/hankuikui/p/11414579.html