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

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS Agent(兼容OpenClaw),2核4GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 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("-","");
    }
}
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
11月前
|
SQL 关系型数据库 MySQL
MySQL 常用函数
我们这次全面梳理 MySQL 中的常用函数,涵盖 聚合函数、字符串函数、日期时间函数、数学函数 和 控制流函数 等五大类。每类函数均配有语法说明与实用示例,帮助读者提升数据处理能力,如统计分析、文本处理、日期计算、条件判断等。文章结尾提供了丰富的实战练习,帮助读者巩固和应用函数技巧,是进阶 SQL 编程与数据分析的实用工具手册。
839 2
|
SQL 关系型数据库 MySQL
【YashanDB知识库】MySQL field 函数的改写方法
【YashanDB知识库】MySQL field 函数的改写方法
|
SQL 关系型数据库 MySQL
Mysql-常用函数及其用法总结
以上列举了MySQL中一些常用的函数及其用法。这些函数在日常的数据库操作中非常实用,能够简化数据查询和处理过程,提高开发效率。掌握这些函数的使用方法,可以更高效地处理和分析数据。
426 19
|
SQL 关系型数据库 MySQL
【MySQL基础篇】盘点MySQL常用四大类函数
本文介绍了MySQL中的四大类常用函数:字符串函数、数值函数、日期函数和流程函数。
【MySQL基础篇】盘点MySQL常用四大类函数
|
SQL 关系型数据库 MySQL
【YashanDB知识库】MySQL field 函数的改写方法
本文来自YashanDB官网,介绍将MySQL的FIELD函数改写到YashanDB的方法。MySQL中,FIELD函数用于自定义排序;而在YashanDB中,可使用DECODE或CASE语句实现类似功能。示例展示对表`t1`按指定顺序排序的过程,提供两种改写方式,结果均符合预期。
|
存储 Oracle 关系型数据库
oracle 数据库 迁移 mysql数据库
将 Oracle 数据库迁移到 MySQL 是一项复杂的任务,因为这两种数据库管理系统具有不同的架构、语法和功能。
439 0
|
存储 Oracle 关系型数据库
oracle迁移mysql数据库注意(转)
oracle转mysql修改:1. substr() substr( string , 0, 10) 这里测试 必须从 第一位获取 既是 substr(string , 1 , 10)2. to_char() 只能用做oracle的函数,兼容oracle和mysql故 改为concat( … , ''); 这里 使用了两个, 一个 是将类似 int 转为 string 3.
1994 0
|
8月前
|
Oracle 关系型数据库 Linux
【赵渝强老师】Oracle数据库配置助手:DBCA
Oracle数据库配置助手(DBCA)是用于创建和配置Oracle数据库的工具,支持图形界面和静默执行模式。本文介绍了使用DBCA在Linux环境下创建数据库的完整步骤,包括选择数据库操作类型、配置存储与网络选项、设置管理密码等,并提供了界面截图与视频讲解,帮助用户快速掌握数据库创建流程。
710 93
|
7月前
|
Oracle 关系型数据库 Linux
【赵渝强老师】使用NetManager创建Oracle数据库的监听器
Oracle NetManager是数据库网络配置工具,用于创建监听器、配置服务命名与网络连接,支持多数据库共享监听,确保客户端与服务器通信顺畅。
390 0
|
10月前
|
存储 Oracle 关系型数据库
服务器数据恢复—光纤存储上oracle数据库数据恢复案例
一台光纤服务器存储上有16块FC硬盘,上层部署了Oracle数据库。服务器存储前面板2个硬盘指示灯显示异常,存储映射到linux操作系统上的卷挂载不上,业务中断。 通过storage manager查看存储状态,发现逻辑卷状态失败。再查看物理磁盘状态,发现其中一块盘报告“警告”,硬盘指示灯显示异常的2块盘报告“失败”。 将当前存储的完整日志状态备份下来,解析备份出来的存储日志并获得了关于逻辑卷结构的部分信息。

推荐镜像

更多