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

原文地址:https://www.cnblogs.com/hankuikui/p/11414579.html

时间: 2024-09-30 02:57:01

Jpa-Spec oracle函数bitand,instr等扩展的相关文章

【函数】Oracle函数系列(1)--字符函数

[函数]Oracle函数系列(1)--字符函数 1  BLOG文档结构图 2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① 常见字符函数(lower.upper.initcap.concat.substr.length.intr.lpad.rpad.trim.chr.ascii.replace.translate)的使用 ② 判断字符串中是否含有汉字 ③ substr和instr的联合使用 ④

Oracle函数-高阶篇

下面整理了部分oracle函数-高阶篇: 1. CATSTR    举例:SELECT CATSTR(COLUMN_NAME) NAME_LIST FROM DBA_TAB_COLUMNS WHERE TRIM(TABLE_NAME) = 'T_RZ_DKDATA'  --查询出的结果在一个列中2. INSTR() 检索字符串函数:匹配则返回首次检索的位置的索引值(从1开始),值>0,否则返回值=0    举例:SELECT * FROM USER_TABLES WHERE INSTR(TABL

ORACLE函数之单行字符函数

 1.           ASCII(C) 说明:返回C的首字符在ASCII码中对应的十进制 举例: SQL>SELECT ASCII('A') A,ASCII('a') B,ASCII('0') C,ASCII(' ') D FROM DUAL; A         B          C         D -------------------- ---------- ---------- 65        97         48        32 2.         C

oracle 函数集锦

oracle的函數很多﹐特整理出來﹕ abs(m)  m的绝对值mod(m,n) m被n除后的余数power(m,n) m的n次方round(m[,n]) m四舍五入至小数点后n位的值(n缺省为0)trunc(m[,n]) m截断n位小数位的值(n缺省为0) 字符函数: initcap(st) 返回st将每个单词的首字母大写,所有其他字母小写lower(st) 返回st将每个单词的字母全部小写upper(st) 返回st将每个单词的字母全部大写concat(st1,st2)  返回st为st2接

oracle 函数学习 Oracle10g学习系列(7)

Oracle函数有字符函数.数学函数.日期函数和转换函数.我只了解了字符函数和数学函数. 一.字符函数: lower(char)  将字符串转化为小写的格式 SQL> select lower(ename),ename from emp; LOWER(ENAME) ENAME ------------ ---------- smith        SMITH allen        ALLEN ward         WARD upper(char)  将字符串转化为大写的格式 SQL>

ORACLE函数之单行数字函数

 1.           ABS(X) 返回X的绝对值 SQL>SELECT ABS(-1) A,ABS(1) B,ABS(0) C FROM DUAL; A          B          C -------------------- ---------- 1          1          0 2.          ACOS(X) 返回X的反余弦值 SQL>SELECT ACOS(0) A,ACOS(0.5) B,ACOS(1) C FROM DUAL; A    

Oracle——函数

CREATE FUNCTION annual_income(spNAme VARCHAR2) RETURN NUMBER IS yearSal number(7,2);BEGIN  SELECT (sal+NVL(comm,0))*12 INTO yearSal FROM emp WHERE ename=spNAme;  RETURN yearSal;END;/ SQL> var income number;SQL> call annual_income('SMITH') into:incom

Oracle函数+for循环

create or replace function FilterMinganci(str in varchar) return varchar2 is filterWorld varchar2(1000); keyCount int; begin filterWorld := str; keyCount := 0; select count(1) into keyCount from dic_keyword; for aa in (select keyword from dic_keyword

java调用oracle函数

今天写了个oracle函数,但但对java如何调用不是很明白. 今天写了个,并且成功运行了. Connection conn = null; CallableStatement cstmt = null; try { conn = this.getJdbcTemplate().getDataSource().getConnection(); cstmt = conn.prepareCall("{call AUTO_TENDER_NVL(?)}"); cstmt.registerOutP