java实现oracle和mysql的group by分组功能|同时具备max()/min()/sum()/case when 函数等功能

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: java实现oracle和mysql的group by分组功能|同时具备max()/min()/sum()/case when 函数等功能

一、前言

oracle和mysql的group by 分组功能大家应该清楚,那如何使用java实现同样的功能呢

比如下面这个表

1695737723920.png

我们需要按id分组,求最大age和math累计成绩

我们的sql应该这样写

select id,max(age),sum(math)
from student
group by id;

得到的数据是这样的

那java应该怎么样实现呢?

二、java实现过程

group by分组实现

public static Map<String, Object> groupBy(Map<String, Object> map, String[] groupFuns) {
        // List list = new ArrayList(groupFuns.length);
        if (groupFuns.length<1){
            return map;
        }
        Map<String, Object> result = new HashMap<>();
        for (int i = 0, length = groupFuns.length; i < length; i++) {
            String field = groupFuns[i];
            if (!map.containsKey(field)) {
                System.out.println("map中未有【" + field + "】字段");
                //log.error("map中未有【{}】字段",field);
                continue;
            }
            Object value = map.get(field);
            if (value == null || StringUtils.isBlank(value.toString())) {
                result.put(field, null);
            } else {
                result.put(field, value);
            }
        }
        return result;
    }

调用分组函数

public static List<Map<String, Object>> partitionGroupBy(List<Map<String, Object>> dataList, String[] groupFuns, String[][] combiFuns) {
        Map<Map<String, Object>, List<Map<String, Object>>> groupByResultMap = dataList.stream().collect(Collectors.groupingBy(o -> groupBy(o, groupFuns)));
        if (MapUtils.isEmpty(groupByResultMap)){
            return new ArrayList<>();
        }
        List<Map<String, Object>> result = new ArrayList<>(groupByResultMap.size());
        for (Map.Entry<Map<String, Object>, List<Map<String, Object>>> entry : groupByResultMap.entrySet()) {
            Map<String, Object> key = entry.getKey();
            List<Map<String, Object>> valueList = entry.getValue();
            // {{"max","advancedate"},{"max","vc_code"},{"sum","cashdivirmb"}};
            Map<String, Object> resultMap = new HashMap<>(16);
            for (int i = 0, length = combiFuns.length; i < length; i++) {
                String[] combiFun = combiFuns[i];
                // 组合函数名称
                String combiFunName = combiFun[0];
                // 字段名称
                String combiFunField = combiFun[1];
                // 别名
                String otherName = StringUtils.isBlank(combiFun[2]) ? combiFunField : combiFun[2];
                switch (combiFunName.toLowerCase()) {
                    case "null":
                        resultMap.put(otherName, null);
                        break;
                    case "field":
                        // 原始字段值,从分组的key里面取值
                        resultMap.put(otherName, key.get(combiFunField));
                        break;
                    case "spel":
                        resultMap.putAll(combiFunSpel(resultMap, combiFunField, otherName,combiFun[3]));
                        break;
                    case "max":
                        resultMap.putAll(combiFunMax(valueList, combiFunField, otherName));
                        break;
                    case "min":
                        resultMap.putAll(combiFunMin(valueList, combiFunField, otherName));
                        break;
                    case "sum":
                        resultMap.putAll(combiFunSum(valueList, combiFunField,otherName));
                        break;
                    default:
                        System.out.println("不存在组合函数【" + combiFunName + "," + combiFunField + "】,请自己实现或者更改成已经有的组合函数");
                        //log.error("不存在组合函数【{},{}】,请自己实现或者更改成已经有的组合函数",combiFunName,combiFunField);
                }
            }
            // List<Map<String, Object>> combiFunFilterList = new ArrayList<>();
            // combiFunFilterList.add(resultMap);
            result.add(resultMap);
        }
        return result;
    }

实现max,sum,min,spel表达式等自定义函数

private static Map<String, Object> combiFunMax(List<Map<String, Object>> list, String combiFunField, String otherName) {
        BigDecimal maxValue = null;
        for (Map<String, Object> map : list) {
            if (!map.containsKey(combiFunField)) {
                System.out.println("map中未有【" + combiFunField + "】字段");
                //log.error("map中未有【{}】字段", combiFunField);
                continue;
            }
            Object tempValueObj = map.get(combiFunField);
            if (tempValueObj == null || StringUtils.isBlank(tempValueObj.toString())) {
                continue;
            }
            BigDecimal tempValue = ComUtils.nvl(map.get(combiFunField), BigDecimal.ZERO);
            if (maxValue == null || tempValue.compareTo(maxValue) > 0) {
                maxValue = tempValue;
            }
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put(otherName, maxValue);
        return resultMap;
    }
    private static Map<String, Object> combiFunMin(List<Map<String, Object>> list, String combiFunField, String otherName) {
        BigDecimal minValue = null;
        for (Map<String, Object> map : list) {
            if (!map.containsKey(combiFunField)) {
                System.out.println("map中未有【" + combiFunField + "】字段");
                //log.error("map中未有【{}】字段", combiFunField);
                continue;
            }
            Object tempValueObj = map.get(combiFunField);
            if (tempValueObj == null || StringUtils.isBlank(tempValueObj.toString())) {
                continue;
            }
            BigDecimal tempValue = ComUtils.nvl(map.get(combiFunField), BigDecimal.ZERO);
            if (minValue == null || tempValue.compareTo(minValue) < 0) {
                minValue = tempValue;
            }
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put(otherName, minValue);
        return resultMap;
    }
    private static SpelCommonUtil spelCommonUtil=new SpelCommonUtil();
    private static Map<String, Object> combiFunSpel(Map<String,Object> map, String combiFunField, String otherName,String spelFun) {
        // spel
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression(spelFun);
        StandardEvaluationContext context = new StandardEvaluationContext();
        context.setRootObject(spelCommonUtil);
        Map<String, Object> resultMap = new HashMap<>();
        context.setVariable("a",map);
        Object value = exp.getValue(context);
        resultMap.put(otherName,value);
        return resultMap;
    }
    private static Map<String, Object> combiFunSum(List<Map<String, Object>> list, String combiFunField,String otherName) {
        BigDecimal sumValue = null;
        for (Map<String, Object> map : list) {
            if (!map.containsKey(combiFunField)) {
                System.out.println("map中未有【" + combiFunField + "】字段");
                //log.error("map中未有【{}】字段", combiFunField);
                continue;
            }
            Object tempValueObj = map.get(combiFunField);
            if (tempValueObj == null || StringUtils.isBlank(tempValueObj.toString())) {
                continue;
            }
            BigDecimal tempValue = ComUtils.nvl(map.get(combiFunField), BigDecimal.ZERO);
            sumValue = tempValue.add(sumValue == null ? BigDecimal.ZERO : sumValue);
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put(otherName, sumValue);
        return resultMap;
    }

测试类调用

public static void main(String[] args) {
        Map<String, Object> map1 = new HashMap<String, Object>() {{
            put("id", 10);
            put("name", "map1");
            put("age", "20");
            put("math", "92.5");
        }};
        Map<String, Object> map2 = new HashMap<String, Object>() {{
            put("id", 103);
            put("name", "map2");
            put("age", "");
            put("math", "84");
        }};
        Map<String, Object> map3 = new HashMap<String, Object>() {{
            put("id", 102);
            put("name", "map3");
            put("age", "5");
            put("math", "20");
        }};
        Map<String, Object> map4 = new HashMap<String, Object>() {{
            put("id", 102);
            put("name", "map4");
            put("age", "6");
            put("math", "1");
        }};
        Map<String, Object> map5 = new HashMap<String, Object>() {{
            put("id", 103);
            put("name", "map5");
            put("age", null);
            put("math", "63");
        }};
        Map<String, Object> map6 = new HashMap<String, Object>() {{
            put("id", 103);
            put("name", "map6");
            put("age", 5);
            put("math", "");
        }};
        Map<String, Object> map7 = new HashMap<String, Object>() {{
            put("id", 10);
            put("name", "map7");
            put("age", "20");
            put("math", "");
        }};
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>() {{
            add(map1);
            add(map2);
            add(map3);
            add(map4);
            add(map5);
            add(map6);
            add(map7);
        }};
        String[] groupFuns = {"id"};
        //String[] groupFuns = {"id","age"};
        // 组合函数,取的字段,别名(如果为空就以取的字段为key),特殊处理函数
        //String[][] combiFuns = {{"min", "age", "", ""}, {"field", "id", "", ""}, {"sum", "math", "", ""},{"spel", "age", "spel", "decode(#a.get(\"age\"),5,\"优秀\",\"不优秀\")"}};
        // String[][] combiFuns = {{"min", "age", "", ""}, {"field", "id", "", ""}, {"sum", "math", "", ""}};
        String[][] combiFuns = {{"max", "age", "", ""},{"max", "math", "", ""}};
        List<Map<String, Object>> maps = partitionGroupBy(list, groupFuns, combiFuns);
        System.out.println(maps);
        System.out.println(JSON.toJSONString(maps));
    }

执行测试结果

发现和数据库执行的一致,符合要求

复杂情况casewhen函数

那要是还是按id,age分组,sum(math)>60为及格,否则为不及格应该怎么写呢?

sql语句应该为

select id,max(age),sum(math),case when sum(math)>60 then '及格' else '不及格' end as pingjia
from student
group by id,age;

执行结果

java应该怎么实现呢,这里就需要用到spel表达式,不了解的朋友们可以去找一下资料,这里就不赘述了

这里就得加spel常用的一些表达式,具体请看文末的,spelCommonUtil.class

java测试

分组和函数配置如下

public static void main(String[] args) {
        Map<String, Object> map1 = new HashMap<String, Object>() {{
            put("id", 10);
            put("name", "map1");
            put("age", "20");
            put("math", "92.5");
        }};
        Map<String, Object> map2 = new HashMap<String, Object>() {{
            put("id", 103);
            put("name", "map2");
            put("age", "");
            put("math", "84");
        }};
        Map<String, Object> map3 = new HashMap<String, Object>() {{
            put("id", 102);
            put("name", "map3");
            put("age", "5");
            put("math", "20");
        }};
        Map<String, Object> map4 = new HashMap<String, Object>() {{
            put("id", 102);
            put("name", "map4");
            put("age", "6");
            put("math", "1");
        }};
        Map<String, Object> map5 = new HashMap<String, Object>() {{
            put("id", 103);
            put("name", "map5");
            put("age", null);
            put("math", "63");
        }};
        Map<String, Object> map6 = new HashMap<String, Object>() {{
            put("id", 103);
            put("name", "map6");
            put("age", 5);
            put("math", "");
        }};
        Map<String, Object> map7 = new HashMap<String, Object>() {{
            put("id", 10);
            put("name", "map7");
            put("age", "20");
            put("math", "");
        }};
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>() {{
            add(map1);
            add(map2);
            add(map3);
            add(map4);
            add(map5);
            add(map6);
            add(map7);
        }};
        //String[] groupFuns = {"id"};
        String[] groupFuns = {"id","age"};
        // 组合函数,取的字段,别名(如果为空就以取的字段为key),特殊处理函数
        //String[][] combiFuns = {{"min", "age", "", ""}, {"field", "id", "", ""}, {"sum", "math", "", ""},{"spel", "age", "spel", "decode(#a.get(\"age\"),5,\"优秀\",\"不优秀\")"}};
        // String[][] combiFuns = {{"min", "age", "", ""}, {"field", "id", "", ""}, {"sum", "math", "", ""}};
        //String[][] combiFuns = {{"field", "id", "", ""},{"max", "age", "", ""},{"max", "math", "", ""}};
        //String[][] combiFuns = {{"field", "id", "", ""},{"max", "age", "", ""},{"sum", "math", "", ""}};
        String[][] combiFuns = {{"field", "id", "", ""},{"max", "age", "", ""},{"sum", "math", "", ""},{"spel","math","pingjia","caseWhen(\"不及格\",#a.get(\"math\")>60,\"及格\")"}};
        List<Map<String, Object>> maps = partitionGroupBy(list, groupFuns, combiFuns);
        System.out.println(maps);
        System.out.println(JSON.toJSONString(maps));
    }

执行结果

结果和sql执行一致,符合要求,

优化代码

综上所述,代码符合要求,但是有一种情况该方法就无法实现,比如我们需要求按id和age分组,同时满足max(age)>5 和 sum(math)>60 的,上述代码就无法实现,因为这里出现了分组函数和case when函数同时出现的情况

我们将在另外的代码中优化,具体请看下期

三、完整代码

import com.alibaba.fastjson.JSON;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Test14 {
    public static void main(String[] args) {
        Map<String, Object> map1 = new HashMap<String, Object>() {{
            put("id", 10);
            put("name", "map1");
            put("age", "20");
            put("math", "92.5");
        }};
        Map<String, Object> map2 = new HashMap<String, Object>() {{
            put("id", 103);
            put("name", "map2");
            put("age", "");
            put("math", "84");
        }};
        Map<String, Object> map3 = new HashMap<String, Object>() {{
            put("id", 102);
            put("name", "map3");
            put("age", "5");
            put("math", "20");
        }};
        Map<String, Object> map4 = new HashMap<String, Object>() {{
            put("id", 102);
            put("name", "map4");
            put("age", "6");
            put("math", "1");
        }};
        Map<String, Object> map5 = new HashMap<String, Object>() {{
            put("id", 103);
            put("name", "map5");
            put("age", null);
            put("math", "63");
        }};
        Map<String, Object> map6 = new HashMap<String, Object>() {{
            put("id", 103);
            put("name", "map6");
            put("age", 5);
            put("math", "");
        }};
        Map<String, Object> map7 = new HashMap<String, Object>() {{
            put("id", 10);
            put("name", "map7");
            put("age", "20");
            put("math", "");
        }};
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>() {{
            add(map1);
            add(map2);
            add(map3);
            add(map4);
            add(map5);
            add(map6);
            add(map7);
        }};
        //String[] groupFuns = {"id"};
        String[] groupFuns = {"id","age"};
        // 组合函数,取的字段,别名(如果为空就以取的字段为key),特殊处理函数
        //String[][] combiFuns = {{"min", "age", "", ""}, {"field", "id", "", ""}, {"sum", "math", "", ""},{"spel", "age", "spel", "decode(#a.get(\"age\"),5,\"优秀\",\"不优秀\")"}};
        // String[][] combiFuns = {{"min", "age", "", ""}, {"field", "id", "", ""}, {"sum", "math", "", ""}};
        //String[][] combiFuns = {{"field", "id", "", ""},{"max", "age", "", ""},{"max", "math", "", ""}};
        //String[][] combiFuns = {{"field", "id", "", ""},{"max", "age", "", ""},{"sum", "math", "", ""}};
        String[][] combiFuns = {{"field", "id", "", ""},{"max", "age", "", ""},{"sum", "math", "", ""},{"spel","math","pingjia","caseWhen(\"不及格\",#a.get(\"math\")>60,\"及格\")"}};
        List<Map<String, Object>> maps = partitionGroupBy(list, groupFuns, combiFuns);
        System.out.println(maps);
        System.out.println(JSON.toJSONString(maps));
    }
    public static List<Map<String, Object>> partitionGroupBy(List<Map<String, Object>> dataList, String[] groupFuns, String[][] combiFuns) {
        Map<Map<String, Object>, List<Map<String, Object>>> groupByResultMap = dataList.stream().collect(Collectors.groupingBy(o -> groupBy(o, groupFuns)));
        if (MapUtils.isEmpty(groupByResultMap)){
            return new ArrayList<>();
        }
        List<Map<String, Object>> result = new ArrayList<>(groupByResultMap.size());
        for (Map.Entry<Map<String, Object>, List<Map<String, Object>>> entry : groupByResultMap.entrySet()) {
            Map<String, Object> key = entry.getKey();
            List<Map<String, Object>> valueList = entry.getValue();
            // {{"max","advancedate"},{"max","vc_code"},{"sum","cashdivirmb"}};
            Map<String, Object> resultMap = new HashMap<>(16);
            for (int i = 0, length = combiFuns.length; i < length; i++) {
                String[] combiFun = combiFuns[i];
                // 组合函数名称
                String combiFunName = combiFun[0];
                // 字段名称
                String combiFunField = combiFun[1];
                // 别名
                String otherName = StringUtils.isBlank(combiFun[2]) ? combiFunField : combiFun[2];
                switch (combiFunName.toLowerCase()) {
                    case "null":
                        resultMap.put(otherName, null);
                        break;
                    case "field":
                        // 原始字段值,从分组的key里面取值
                        resultMap.put(otherName, key.get(combiFunField));
                        break;
                    case "spel":
                        resultMap.putAll(combiFunSpel(resultMap, combiFunField, otherName,combiFun[3]));
                        break;
                    case "max":
                        resultMap.putAll(combiFunMax(valueList, combiFunField, otherName));
                        break;
                    case "min":
                        resultMap.putAll(combiFunMin(valueList, combiFunField, otherName));
                        break;
                    case "sum":
                        resultMap.putAll(combiFunSum(valueList, combiFunField,otherName));
                        break;
                    default:
                        System.out.println("不存在组合函数【" + combiFunName + "," + combiFunField + "】,请自己实现或者更改成已经有的组合函数");
                        //log.error("不存在组合函数【{},{}】,请自己实现或者更改成已经有的组合函数",combiFunName,combiFunField);
                }
            }
            // List<Map<String, Object>> combiFunFilterList = new ArrayList<>();
            // combiFunFilterList.add(resultMap);
            result.add(resultMap);
        }
        return result;
    }
    public static Map<String, Object> groupBy(Map<String, Object> map, String[] groupFuns) {
        // List list = new ArrayList(groupFuns.length);
        if (groupFuns.length<1){
            return map;
        }
        Map<String, Object> result = new HashMap<>();
        for (int i = 0, length = groupFuns.length; i < length; i++) {
            String field = groupFuns[i];
            if (!map.containsKey(field)) {
                System.out.println("map中未有【" + field + "】字段");
                //log.error("map中未有【{}】字段",field);
                continue;
            }
            Object value = map.get(field);
            if (value == null || StringUtils.isBlank(value.toString())) {
                result.put(field, null);
            } else {
                result.put(field, value);
            }
        }
        return result;
    }
    private static Map<String, Object> combiFunMax(List<Map<String, Object>> list, String combiFunField, String otherName) {
        BigDecimal maxValue = null;
        for (Map<String, Object> map : list) {
            if (!map.containsKey(combiFunField)) {
                System.out.println("map中未有【" + combiFunField + "】字段");
                //log.error("map中未有【{}】字段", combiFunField);
                continue;
            }
            Object tempValueObj = map.get(combiFunField);
            if (tempValueObj == null || StringUtils.isBlank(tempValueObj.toString())) {
                continue;
            }
            BigDecimal tempValue = ComUtils.nvl(map.get(combiFunField), BigDecimal.ZERO);
            if (maxValue == null || tempValue.compareTo(maxValue) > 0) {
                maxValue = tempValue;
            }
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put(otherName, maxValue);
        return resultMap;
    }
    private static Map<String, Object> combiFunMin(List<Map<String, Object>> list, String combiFunField, String otherName) {
        BigDecimal minValue = null;
        for (Map<String, Object> map : list) {
            if (!map.containsKey(combiFunField)) {
                System.out.println("map中未有【" + combiFunField + "】字段");
                //log.error("map中未有【{}】字段", combiFunField);
                continue;
            }
            Object tempValueObj = map.get(combiFunField);
            if (tempValueObj == null || StringUtils.isBlank(tempValueObj.toString())) {
                continue;
            }
            BigDecimal tempValue = ComUtils.nvl(map.get(combiFunField), BigDecimal.ZERO);
            if (minValue == null || tempValue.compareTo(minValue) < 0) {
                minValue = tempValue;
            }
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put(otherName, minValue);
        return resultMap;
    }
    private static SpelCommonUtil spelCommonUtil=new SpelCommonUtil();
    private static Map<String, Object> combiFunSpel(Map<String,Object> map, String combiFunField, String otherName,String spelFun) {
        // spel
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression(spelFun);
        StandardEvaluationContext context = new StandardEvaluationContext();
        context.setRootObject(spelCommonUtil);
        Map<String, Object> resultMap = new HashMap<>();
        context.setVariable("a",map);
        Object value = exp.getValue(context);
        resultMap.put(otherName,value);
        return resultMap;
    }
    private static Map<String, Object> combiFunSum(List<Map<String, Object>> list, String combiFunField,String otherName) {
        BigDecimal sumValue = null;
        for (Map<String, Object> map : list) {
            if (!map.containsKey(combiFunField)) {
                System.out.println("map中未有【" + combiFunField + "】字段");
                //log.error("map中未有【{}】字段", combiFunField);
                continue;
            }
            Object tempValueObj = map.get(combiFunField);
            if (tempValueObj == null || StringUtils.isBlank(tempValueObj.toString())) {
                continue;
            }
            BigDecimal tempValue = ComUtils.nvl(map.get(combiFunField), BigDecimal.ZERO);
            sumValue = tempValue.add(sumValue == null ? BigDecimal.ZERO : sumValue);
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put(otherName, sumValue);
        return resultMap;
    }
}

ComUtils.class

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
public class ComUtils {
    /**
     * SpelCommonUtil
     */
    private static SpelCommonUtil spelCommonUtil = new SpelCommonUtil();
    /**
     * nvl转换函数
     *
     * @param obj1
     * @param obj2
     * @return
     */
    public static BigDecimal nvl(Object obj1, BigDecimal obj2) {
        if (obj1 == null) {
            return obj2;
        }
        if (StringUtils.isBlank(obj1.toString())) {
            return obj2;
        }
        return new BigDecimal(obj1.toString());
    }
    /**
     * nvl转换函数
     *
     * @param obj1
     * @param obj2
     * @return
     */
    public static String nvl(Object obj1, String obj2) {
        if (obj1 == null) {
            return obj2;
        }
        if (StringUtils.isBlank(obj1.toString())) {
            return obj2;
        }
        return obj1.toString();
    }
}

SpelCommonUtil.class

package com.zygxsq.test.util;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;
public class SpelCommonUtil {
    private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyyMMdd");
        }
    };
    /**
     * 日期格式转换为Integer
     * @date 2022-10-21 17:06
     * @param date
     * @return java.lang.Integer
     **/
    public static Integer dateToInt(Date date){
        if (null==date){
            return null;
        }
       return Integer.valueOf( threadLocal.get().format(date));
    }
    /**
     * 相除
     * 修正原因:保留精度 默认保留小数位 10位
     * 入参格式:division(#a.get('xxx'),100,4)-》表示除以100 保留4位
     * 注意点:
     * 精度具体值 来源于具体表的具体字段的数据定义
     * @param numerator
     * @param denominator
     * @return
     */
    public static BigDecimal division(Object numerator , Object... values){
        if (null ==numerator){
            return null;
        }
        if (null==values || values.length<=0){
            return null;
        }
        Object denominator = values[0];
        if (denominator == null){
            return null;
        }
        BigDecimal numeratorDouble=new BigDecimal(numerator.toString());
        BigDecimal denominatorDouble=new BigDecimal(denominator.toString());
        if (denominatorDouble.doubleValue()==0){
            return null;
        }
        // 默认保留 10位
        int scale = 10;
        // 传入精度时 替换
        if (values.length>1){
            scale = values[1] != null? Integer.valueOf(values[1].toString()) :scale;
        }
        return numeratorDouble.divide(denominatorDouble,scale,BigDecimal.ROUND_HALF_UP);
    }
    /**
     * 相乘
     * 修改原因:精度的问题
     * @param numerator
     * @param denominator
     * @return
     */
    public static BigDecimal multiply(Object numerator , Object denominator){
        if (null ==numerator||null==denominator){
            return null;
        }
        BigDecimal numeratorBigDecimal=new BigDecimal(numerator.toString());
        BigDecimal denominatorBigDecimal=new BigDecimal(denominator.toString());
        return numeratorBigDecimal.multiply(denominatorBigDecimal);
    }
    /**
     * 相减
     * @param num1 被减数
     * @param num2 减数
     * @return
     */
    public static BigDecimal subtract(Object num1, Object num2){
        if (null == num1 || null == num2){
            return null;
        }
        BigDecimal bigDecimal1 = new BigDecimal(num1.toString());
        BigDecimal bigDecimal2 = new BigDecimal(num2.toString());
        return bigDecimal1.subtract(bigDecimal2);
    }
    /**
     * 获取当前日期
     * 
     * @date 2022-10-21 17:10
     * @return java.util.Date
     **/
    public  static  Date now(){
        return new Date();
    }
    /**
     * 三目运算
     * @param obj1
     * @param obj2
     * @return
     */
    public static Object nvl(Object obj1 , Object obj2){
        return null == obj1?obj2:obj1;
    }
    /**
     * 三目运算
     * @param obj1
     * @param obj2
     * @return
     */
    public static Object nvl2(Object obj1 , Object obj2, Object obj3){
        return null == obj1?obj3:obj2;
    }
    /**
     * 字符串截取,对应Oracle substr 例如:substr(#t.get("dm"), 1, 4)
     * @param obj
     * @param index
     * @return
     */
    public static String substr(Object obj, Integer... index) {
        StringBuilder result = new StringBuilder();
        if (null == obj) {
            return result.toString();
        }
        String str = obj.toString();
        // 针对 从后面截取
        if (index.length == 1) {
            // 如截取 -2
            if (index[0] < 0 && Math.abs(index[0]) <= str.length()) {
                return str.substring(str.length()+ index[0]);
            }
            // 超过 返回空字符串
            if (index[0] < 0 && Math.abs(index[0]) > str.length()) {
                return "";
            }
        }
        if (index.length==2){
            if (index[0] == 0 || index[0] == 1){
                if (index[0]+index[1]-1>str.length()){
                    result.append(str.substring(0,str.length()));
                }else{
                    result.append(str.substring(0,index[0]+index[1]-1));
                }
            }else{
                if (index[0]+index[1]-1>str.length()){
                    result.append(str.substring(index[0]-1,str.length()));
                }else{
                    result.append(str.substring(index[0]-1,index[0]+index[1]-1));
                }
            }
        }else if (index.length==1){
            if (index[0] == 0 || index[0] == 1){
                result.append(str.substring(0));
            }else{
                result.append(str.substring(index[0]-1));
            }
        }else{
            result.append(str);
        }
        return result.toString();
    }
    /**
     * 字符串拼接 对应Oracle || 例如:append("2",#a.get("id"))
     * @param strs
     * @return
     */
    public static String append(Object... strs){
        StringBuilder result = new StringBuilder();
        for (int i=0;i<strs.length;i++){
            if (null != strs[i]){
                result.append(strs[i]);
            }
        }
        return result.toString();
    }
    /**
     * 条件判断  例:caseWhen(默认值,条件1,值1,条件2,值2) 例如:caseWhen(0,in(#a.get("companynature"),"(172,420)"),1)
     * @param defaultValue 默认值
     * @param conditions 条件
     * @return
     */
    public static Object caseWhen(Object defaultValue, Object... conditions){
        Object result = defaultValue;
        for (int i=0;i<conditions.length;){
            if ("true".equals(conditions[i].toString())){
                result = conditions[i+1];
                break;
            }
            i=i+2;
        }
        return result;
    }
    /**
     * oracle 的decode函数,不支持value为null,有为null请使用caseWhen()
     * 例:decode(#a.get("companynature"),1,1,19,2,20,3,null)
     * @param value
     * @param conditions
     * @return
     */
    public static Object decode(Object value, Object... conditions) {
        if (conditions == null) {
            throw new BatchException("decode值不能为空");
        }
        int three = 3;
        int one = 1;
        if (conditions.length < three || (conditions.length & one) == 0) {
            throw new BatchException("decode值不符合要求");
        }
        Object result = conditions[conditions.length - 1];
        if (value == null) {
            return result;
        }
        for (int i = 0; i < conditions.length; ) {
            if (conditions[i] == null) {
                throw new BatchException("decode中的比较值不能为null");
            }
            if (value != null && conditions[i] != null) {
                if (StringUtils.equals(value.toString(), conditions[i].toString())) {
                    result = conditions[i + 1];
                    break;
                }
            } else if (value == null && conditions[i] == null) {
                result = conditions[i + 1];
                break;
            }
            i = i + 2;
        }
        return result;
    }
    /**
     *
     * @param obj in(#a.get("companynature"),"172,420"))
     * @param condition
     * @return
     */
    public static boolean in(Object obj, String condition){
        if (StringUtils.isBlank(condition) || obj == null){
            return false;
        }
        String[] values = condition.split(",");
        List<String> valueList = new ArrayList(Arrays.asList(values));
        return valueList.contains(obj);
    }
    /** 对应数值类型
     * @param obj       in(#a.get("l_market"),1,2))
     * @param condition
     * @return
     */
    public static boolean in(Object obj, Integer... condition) {
        if (condition.length == 0 || obj == null) {
            return false;
        }
        if (obj instanceof BigDecimal || obj instanceof Double) {
            obj = ((Number) obj).intValue();
        }
        List<Integer> valueList = new ArrayList(Arrays.asList(condition));
        return valueList.contains(obj);
    }
    /**
     * 不在 -> true
     * @param obj inNot(#a.get("companynature"),"172,420"))
     * @param condition
     * @return
     */
    public static boolean inNot(Object obj, String condition){
        if (StringUtils.isBlank(condition) || obj == null){
            return false;
        }
        String[] values = condition.split(",");
        List<String> valueList = new ArrayList(Arrays.asList(values));
        return !valueList.contains(obj);
    }
    /**
     * 对应数据库左like,例如:%11
     * @param obj
     * @param condition
     * @return
     */
    public static boolean likeOnLeft(Object obj,String condition){
        if (null == obj){
            return false;
        }
        return obj.toString().endsWith(condition);
    }
    /**
     * 对应数据库右like,例如:11%  likeOnRight(#a.get("chiname"),"中华人民共和国")
     * @param obj
     * @param condition
     * @return
     */
    public static boolean likeOnRight(Object obj,String condition){
        if (null == obj){
            return false;
        }
        return obj.toString().startsWith(condition);
    }
    /**
     * 对应数据库like,例如:11%22
     * @param obj
     * @param condition
     * @return
     */
    public static boolean likeOnCenter(Object obj,String condition){
        if (null == obj){
            return false;
        }
        return obj.toString().contains(condition);
    }
    /**
     * 对应数据库to_char,当需要转换的类型为日期格式,可以传第二个参数,例如"yyyyMMdd",默认"yyyyMMdd"
     * @param obj
     * @return
     */
    public static String toString(Object... obj){
        String defaultFormat = "yyyyMMdd";
        if (obj.length == 1){
            if (null == obj[0]){
                return null;
            }else{
                return obj[0].toString();
            }
        }else if (obj.length == 2){
            if (null == obj[0]) {
                return null;
            }
            if (obj[0] instanceof Date){
                if (ObjectUtils.isNotEmpty(obj[1])){
                    SimpleDateFormat sdf;
                    // 容错 避免因为大小写的问题
                    if (defaultFormat.equalsIgnoreCase(obj[1].toString())) {
                        sdf = new SimpleDateFormat(defaultFormat);
                    }
                    else {
                         sdf = new SimpleDateFormat(obj[1].toString());
                    }
                    return sdf.format(obj[0]);
                } else {
                    SimpleDateFormat sdf = new SimpleDateFormat(defaultFormat);
                    return sdf.format(obj[0]);
                }
            }else{
                return obj[0].toString();
            }
        }else{
            return null;
        }
    }
    /**
     * 对应数据库to_char,当需要转换的类型为日期格式,可以传第二个参数,例如"yyyyMMdd",默认"yyyyMMdd"
     * @param obj
     * @return
     */
    public static String toChar(Object... obj){
        return toString(obj);
    }
    /**
     * 对应数据库to_number
     * @param obj
     * @return
     */
    public static Integer toNumber(Object obj){
        if (ObjectUtils.isEmpty(obj)){
            return null;
        }
        if (obj instanceof String){
            return Integer.valueOf(obj.toString());
        }
        return null;
    }
    /**
     * 系统参数校验
     * 
     * @date 2022-12-01 15:26
     * @param paramKey
     * @param paramValue
     * @return boolean
     **/
    public static boolean readtsysparameter(Integer paramKey,String paramValue){
        String param= LoadDataConfigCache.getTetlparameterByKey(paramKey);
        if (StringUtils.isBlank(param)){
            return false;
        }
        if (param.equals(paramValue)){
            return true;
        }
        return false;
    }
    /**
     * 对应Oracle instr 判断str1中是否包含str2
     * @param str1
     * @param str2
     * @return
     */
    public static boolean contains(String str1, String str2){
        if (StringUtils.isEmpty(str1)){
            return false;
        }
        return str1.contains(str2);
    }
    /**
     * 去空格 例如:trim(#a.get("businessmajor"))
     * @param str
     * @return
     */
    public static String trim(Object str){
        String result = "";
        if (null == str){
            return result;
        }
        if (str instanceof String){
            result = str.toString().trim();
        }
        return result;
    }
    /**
     * 对应Oracle replace
     * @param str
     * @param str1
     * @param str2
     * @return
     */
    public static String replace(String str, String str1, String str2){
        return str.replace(str1,str2);
    }
    /**
     * 对应Oracle upper
     * @param str
     * @return
     */
    public static String upper(String str){
        return str.toUpperCase();
    }
    /**
     * 对应Oracle lower
     * @param str
     * @return
     */
    public static String lower(String str){
        return str.toLowerCase();
    }
    /**
     * 对应Oracle =
     * @param obj1
     * @param obj2
     * @return
     */
    public static boolean equal(Object obj1, Object obj2){
        if (null == obj1){
            return false;
        }
        return obj1.equals(obj2);
    }
    /** 不相等
     * 对应Oracle != 和 <>
     * @param obj1
     * @param obj2
     * @return
     */
    public static boolean equalNot(Object obj1, Object obj2){
        if (null == obj1){
            return false;
        }
        return !obj1.equals(obj2);
    }
    /**
     * 对应Oracle round
     * @param number
     * @param decimals
     * @return
     */
    public static BigDecimal round(Object number, int decimals){
        BigDecimal result = new BigDecimal(0);
        if (number instanceof Double){
            result = new BigDecimal((double) number);
        }
        else if (number instanceof Integer){
            result = new BigDecimal((int) number);
        }
        else if (number instanceof String){
            result = new BigDecimal((String) number);
        } else if (number instanceof BigDecimal){
            result=(BigDecimal) number;
        }
        return result.setScale(decimals, BigDecimal.ROUND_HALF_UP);
    }
    /**
     * oracle中sys_guid()
     * @return
     */
    public static String guid(){
        return UUID.randomUUID().toString().replaceAll("-","");
    }
}
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
12天前
|
Java
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
75 34
|
12天前
|
NoSQL Java 关系型数据库
Liunx部署java项目Tomcat、Redis、Mysql教程
本文详细介绍了如何在 Linux 服务器上安装和配置 Tomcat、MySQL 和 Redis,并部署 Java 项目。通过这些步骤,您可以搭建一个高效稳定的 Java 应用运行环境。希望本文能为您在实际操作中提供有价值的参考。
73 26
|
1月前
|
安全 Java 测试技术
🎉Java零基础:全面解析枚举的强大功能
【10月更文挑战第19天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
119 60
|
15天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
26天前
|
关系型数据库 MySQL Java
MySQL索引优化与Java应用实践
【11月更文挑战第25天】在大数据量和高并发的业务场景下,MySQL数据库的索引优化是提升查询性能的关键。本文将深入探讨MySQL索引的多种类型、优化策略及其在Java应用中的实践,通过历史背景、业务场景、底层原理的介绍,并结合Java示例代码,帮助Java架构师更好地理解并应用这些技术。
26 2
|
1月前
|
监控 前端开发 Java
【技术开发】接口管理平台要用什么技术栈?推荐:Java+Vue3+Docker+MySQL
该文档介绍了基于Java后端和Vue3前端构建的管理系统的技术栈及功能模块,涵盖管理后台的访问、登录、首页概览、API接口管理、接口权限设置、接口监控、计费管理、账号管理、应用管理、数据库配置、站点配置及管理员个人设置等内容,并提供了访问地址及操作指南。
|
1月前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
30 2
|
2月前
|
SQL Java 关系型数据库
java连接mysql查询数据(基础版,无框架)
【10月更文挑战第12天】该示例展示了如何使用Java通过JDBC连接MySQL数据库并查询数据。首先在项目中引入`mysql-connector-java`依赖,然后通过`JdbcUtil`类中的`main`方法实现数据库连接、执行SQL查询及结果处理,最后关闭相关资源。
152 6
|
2月前
|
Java 程序员
在Java编程中,关键字不仅是简单的词汇,更是赋予代码强大功能的“魔法咒语”。
【10月更文挑战第13天】在Java编程中,关键字不仅是简单的词汇,更是赋予代码强大功能的“魔法咒语”。本文介绍了Java关键字的基本概念及其重要性,并通过定义类和对象、控制流程、访问修饰符等示例,展示了关键字的实际应用。掌握这些关键字,是成为优秀Java程序员的基础。
28 3
|
2月前
|
Java 数据安全/隐私保护
Java ffmpeg 实现视频加文字/图片水印功能
【10月更文挑战第22天】在 Java 中使用 FFmpeg 实现视频加文字或图片水印功能,需先安装 FFmpeg 并添加依赖(如 JavaCV)。通过构建 FFmpeg 命令行参数,使用 `drawtext` 滤镜添加文字水印,或使用 `overlay` 滤镜添加图片水印。示例代码展示了如何使用 JavaCV 实现文字水印。
152 1

推荐镜像

更多
下一篇
DataWorks