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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 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("-","");
    }
}
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
18天前
|
SQL Java 关系型数据库
Java连接MySQL数据库环境设置指南
请注意,在实际部署时应该避免将敏感信息(如用户名和密码)硬编码在源码文件里面;应该使用配置文件或者环境变量等更为安全可靠地方式管理这些信息。此外,在处理大量数据时考虑使用PreparedStatement而不是Statement可以提高性能并防止SQL注入攻击;同时也要注意正确处理异常情况,并且确保所有打开过得资源都被正确关闭释放掉以防止内存泄漏等问题发生。
59 13
|
2月前
|
人工智能 Java 关系型数据库
Java的时间处理与Mysql的时间查询
本文总结了Java中时间与日历的常用操作,包括时间的转换、格式化、日期加减及比较,并介绍了MySQL中按天、周、月、季度和年进行时间范围查询的方法,适用于日常开发中的时间处理需求。
|
3月前
|
SQL 关系型数据库 MySQL
MySQL 常用函数
我们这次全面梳理 MySQL 中的常用函数,涵盖 聚合函数、字符串函数、日期时间函数、数学函数 和 控制流函数 等五大类。每类函数均配有语法说明与实用示例,帮助读者提升数据处理能力,如统计分析、文本处理、日期计算、条件判断等。文章结尾提供了丰富的实战练习,帮助读者巩固和应用函数技巧,是进阶 SQL 编程与数据分析的实用工具手册。
297 2
|
4月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
6月前
|
SQL 关系型数据库 MySQL
【YashanDB知识库】MySQL field 函数的改写方法
【YashanDB知识库】MySQL field 函数的改写方法
|
6月前
|
SQL 关系型数据库 MySQL
【YashanDB知识库】MySQL field 函数的改写方法
本文来自YashanDB官网,介绍将MySQL的FIELD函数改写到YashanDB的方法。MySQL中,FIELD函数用于自定义排序;而在YashanDB中,可使用DECODE或CASE语句实现类似功能。示例展示对表`t1`按指定顺序排序的过程,提供两种改写方式,结果均符合预期。
|
7月前
|
存储 Java 关系型数据库
java调用mysql存储过程
在 Java 中调用 MySQL 存储过程主要借助 JDBC(Java Database Connectivity)。其核心原理是通过 JDBC 与 MySQL 建立连接,调用存储过程并处理结果。具体步骤包括:加载 JDBC 驱动、建立数据库连接、创建 CallableStatement 对象、设置存储过程参数并执行调用。此过程实现了 Java 程序与 MySQL 数据库的高效交互。
|
9天前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
46 0
|
22天前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
54 16

推荐镜像

更多