From 5ba4bd4052bec63097a6effc258c917243b5f647 Mon Sep 17 00:00:00 2001 From: hongawen <83944980@qq.com> Date: Thu, 4 May 2023 14:22:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=87=BD=E6=95=B0=E4=B8=B0=E5=AF=8C=20or=20?= =?UTF-8?q?=E6=AD=A3=E5=88=99=20=E5=A4=9Amax=E3=80=81min=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../influx/constant/InfluxDbSqlConstant.java | 5 + .../com/njcn/influx/core/InfluxExecutor.java | 26 +- .../njcn/influx/pojo/StatisticsResult.java | 1 - .../njcn/influx/query/InfluxQueryWrapper.java | 308 +++++++++++++++++- 4 files changed, 313 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/njcn/influx/constant/InfluxDbSqlConstant.java b/src/main/java/com/njcn/influx/constant/InfluxDbSqlConstant.java index 86e6970..53ac4d3 100644 --- a/src/main/java/com/njcn/influx/constant/InfluxDbSqlConstant.java +++ b/src/main/java/com/njcn/influx/constant/InfluxDbSqlConstant.java @@ -69,6 +69,7 @@ public interface InfluxDbSqlConstant { String AS_VALUE = StrPool.C_SPACE + "as value" + StrPool.C_SPACE; String EQ = "="; + String NE = "!="; String QM = "'"; String DQM = "\""; String LBK = "("; @@ -92,9 +93,13 @@ public interface InfluxDbSqlConstant { String BOTTOM = "BOTTOM"; String TOP = "TOP"; String LAST = "LAST"; + String ABS = "ABS"; String DERIVATIVE = "DERIVATIVE"; String NUM_95 = ",95"; String PERCENTILE = "PERCENTILE"; + String REGULAR_PREFIX="~/^"; + String REGULAR_SUFFIX="$/"; + String REGULAR_MIDDLE="|"; /** * “ tz('Asia/Shanghai')” diff --git a/src/main/java/com/njcn/influx/core/InfluxExecutor.java b/src/main/java/com/njcn/influx/core/InfluxExecutor.java index f231403..2ac49c7 100644 --- a/src/main/java/com/njcn/influx/core/InfluxExecutor.java +++ b/src/main/java/com/njcn/influx/core/InfluxExecutor.java @@ -59,20 +59,28 @@ public class InfluxExecutor { Object obj = domainClass.newInstance(); for (int i = 0; i < columnValue.size(); i++) { String columnName = columns.get(i); + //属性名有下划线的替换掉 columnName = columnName.replaceAll(StrPool.UNDERLINE, ""); Field[] declaredFields = domainClass.getDeclaredFields(); for (Field declaredField : declaredFields) { - if(columnName.equalsIgnoreCase(declaredField.getName())){ + if (columnName.equalsIgnoreCase(declaredField.getName())) { //获取属性定义的类型 declaredField.setAccessible(true); - if(declaredField.getType() == Instant.class){ - declaredField.set(obj,InstantUtil.stringToInstant(columnValue.get(i).toString().replace("+08:00", "Z"))); - }else if(declaredField.getType() == String.class){ - declaredField.set(obj,columnValue.get(i).toString()); - }else if(declaredField.getType() == Double.class){ - declaredField.set(obj,Double.parseDouble(columnValue.get(i).toString())); - }else if(declaredField.getType() == Integer.class){ - declaredField.set(obj,Integer.parseInt(columnValue.get(i).toString())); + //时间格式 + if (declaredField.getType() == Instant.class) { + declaredField.set(obj, InstantUtil.stringToInstant(columnValue.get(i).toString().replace("+08:00", "Z"))); + //字符串 + } else if (declaredField.getType() == String.class) { + declaredField.set(obj, columnValue.get(i).toString()); + //浮点双精度 + } else if (declaredField.getType() == Double.class) { + declaredField.set(obj, Double.parseDouble(columnValue.get(i).toString())); + //浮点 + } else if (declaredField.getType() == Float.class) { + declaredField.set(obj, Float.parseFloat(columnValue.get(i).toString())); + //整型 + } else if (declaredField.getType() == Integer.class) { + declaredField.set(obj, Integer.parseInt(columnValue.get(i).toString())); } } } diff --git a/src/main/java/com/njcn/influx/pojo/StatisticsResult.java b/src/main/java/com/njcn/influx/pojo/StatisticsResult.java index 0eba147..132526c 100644 --- a/src/main/java/com/njcn/influx/pojo/StatisticsResult.java +++ b/src/main/java/com/njcn/influx/pojo/StatisticsResult.java @@ -5,7 +5,6 @@ import com.njcn.common.utils.serializer.InstantDateSerializer; import lombok.Data; import java.io.Serializable; -import java.math.BigDecimal; import java.time.Instant; /** diff --git a/src/main/java/com/njcn/influx/query/InfluxQueryWrapper.java b/src/main/java/com/njcn/influx/query/InfluxQueryWrapper.java index 3ea9990..8eddf95 100644 --- a/src/main/java/com/njcn/influx/query/InfluxQueryWrapper.java +++ b/src/main/java/com/njcn/influx/query/InfluxQueryWrapper.java @@ -105,7 +105,7 @@ public class InfluxQueryWrapper { .append(StrPool.C_SPACE) .append(InfluxDbSqlConstant.AS) .append(StrPool.C_SPACE) - .append(fieldStr) + .append(this.getColumnName(resultEntity, LambdaUtil.columnToString(fieldStr))) .append(StrPool.C_SPACE); selectColumns.add(selectFragment.toString()); }); @@ -137,17 +137,31 @@ public class InfluxQueryWrapper { * 输出COUNT("columnName") */ public InfluxQueryWrapper count(ICFunction columnName) { + return count(columnName, columnName); + } + + /*** + * 统计记录数 + * @author hongawen + * @param columnName 表字段名 + * @return InfluxQueryWrapper + * 输出COUNT("columnName") as resultName + */ + public InfluxQueryWrapper count(ICFunction columnName, ICFunction resultName) { String selectFragment = InfluxDbSqlConstant.COUNT + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + - this.getColumnName(measurement, LambdaUtil.columnToString(columnName))+ + this.getColumnName(measurement, LambdaUtil.columnToString(columnName)) + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + - InfluxDbSqlConstant.AS_VALUE; + InfluxDbSqlConstant.AS + + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } + /*** * 统计平均值 * @author hongawen @@ -156,13 +170,26 @@ public class InfluxQueryWrapper { * 输出MEAN("columnName") */ public InfluxQueryWrapper mean(ICFunction columnName) { + return mean(columnName, columnName); + } + + /*** + * 统计平均值 + * @author hongawen + * @param columnName 表字段名 + * @return InfluxQueryWrapper + * 输出MEAN("columnName") as resultName + */ + public InfluxQueryWrapper mean(ICFunction columnName, ICFunction resultName) { String selectFragment = InfluxDbSqlConstant.AVG + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + - this.getColumnName(measurement, LambdaUtil.columnToString(columnName))+ + this.getColumnName(measurement, LambdaUtil.columnToString(columnName)) + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + - InfluxDbSqlConstant.AS_VALUE; + InfluxDbSqlConstant.AS + + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } @@ -176,13 +203,26 @@ public class InfluxQueryWrapper { * 输出MEDIAN("columnName") */ public InfluxQueryWrapper median(ICFunction columnName) { + return median(columnName, columnName); + } + + /*** + * 统计中位数 + * @author hongawen + * @param columnName 表字段名 + * @return InfluxQueryWrapper + * 输出MEDIAN("columnName") as resultName + */ + public InfluxQueryWrapper median(ICFunction columnName, ICFunction resultName) { String selectFragment = InfluxDbSqlConstant.MEDIAN + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + this.getColumnName(measurement, LambdaUtil.columnToString(columnName)) + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + - InfluxDbSqlConstant.AS_VALUE; + InfluxDbSqlConstant.AS + + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } @@ -195,13 +235,26 @@ public class InfluxQueryWrapper { * 输出MODE("columnName") */ public InfluxQueryWrapper mode(ICFunction columnName) { + return mode(columnName, columnName); + } + + /*** + * 统计指定字段的最常出现的值 + * @author hongawen + * @param columnName 表字段名 + * @return InfluxQueryWrapper + * 输出MODE("columnName") as resultName + */ + public InfluxQueryWrapper mode(ICFunction columnName, ICFunction resultName) { String selectFragment = InfluxDbSqlConstant.MODE + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + this.getColumnName(measurement, LambdaUtil.columnToString(columnName)) + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + - InfluxDbSqlConstant.AS_VALUE; + InfluxDbSqlConstant.AS + + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } @@ -214,13 +267,26 @@ public class InfluxQueryWrapper { * 输出SPREAD("columnName") */ public InfluxQueryWrapper spread(ICFunction columnName) { + return spread(columnName, columnName); + } + + /*** + * 统计指定字段最大值和最小值的差 + * @author hongawen + * @param columnName 表字段名 + * @return InfluxQueryWrapper + * 输出SPREAD("columnName") as resultName + */ + public InfluxQueryWrapper spread(ICFunction columnName, ICFunction resultName) { String selectFragment = InfluxDbSqlConstant.SPREAD + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + this.getColumnName(measurement, LambdaUtil.columnToString(columnName)) + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + - InfluxDbSqlConstant.AS_VALUE; + InfluxDbSqlConstant.AS + + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } @@ -233,13 +299,26 @@ public class InfluxQueryWrapper { * 输出SUM("columnName") */ public InfluxQueryWrapper sum(ICFunction columnName) { + return sum(columnName, columnName); + } + + /*** + * 统计指定字段值求和 + * @author hongawen + * @param columnName 表字段名 + * @return InfluxQueryWrapper + * 输出SUM("columnName") as resultName + */ + public InfluxQueryWrapper sum(ICFunction columnName, ICFunction resultName) { String selectFragment = InfluxDbSqlConstant.SUM + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + this.getColumnName(measurement, LambdaUtil.columnToString(columnName)) + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + - InfluxDbSqlConstant.AS_VALUE; + InfluxDbSqlConstant.AS + + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } @@ -326,6 +405,37 @@ public class InfluxQueryWrapper { return this; } + /*** + * 统计指定字段绝对值 + * @author hongawen + * @param columnName 表字段名 + * @return InfluxQueryWrapper + * 输出ABS("columnName") + */ + public InfluxQueryWrapper abs(ICFunction columnName) { + return abs(columnName, columnName); + } + + /*** + * 统计指定字段绝对值 + * @author hongawen + * @param columnName 表字段名 + * @return InfluxQueryWrapper + * 输出ABS("columnName") as resultName + */ + public InfluxQueryWrapper abs(ICFunction columnName, ICFunction resultName) { + String selectFragment = InfluxDbSqlConstant.ABS + + InfluxDbSqlConstant.LBK + + InfluxDbSqlConstant.DQM + + this.getColumnName(measurement, LambdaUtil.columnToString(columnName)) + + InfluxDbSqlConstant.DQM + + InfluxDbSqlConstant.RBK + + InfluxDbSqlConstant.AS + + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + + StrPool.C_SPACE; + selectColumns.add(selectFragment); + return this; + } /*** * 获取指定字段最大值 @@ -335,7 +445,7 @@ public class InfluxQueryWrapper { * 输出 MAX("columnName") */ public InfluxQueryWrapper max(ICFunction columnName) { - return max(columnName, "value"); + return max(columnName, columnName); } /*** @@ -346,7 +456,7 @@ public class InfluxQueryWrapper { * @return InfluxQueryWrapper * 输出 MAX("columnName") as resultName */ - public InfluxQueryWrapper max(ICFunction columnName, String resultName) { + public InfluxQueryWrapper max(ICFunction columnName, ICFunction resultName) { String selectFragment = InfluxDbSqlConstant.MAX + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + @@ -354,12 +464,53 @@ public class InfluxQueryWrapper { InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + + StrPool.C_SPACE; + selectColumns.add(selectFragment); + return this; + } + + /*** + * 获取指定字段最大值 + * @author hongawen + * @param columnName 表字段名 + * @param resultName 映射名称 + * @return InfluxQueryWrapper + * 输出 MAX("columnName") as resultName + */ + public InfluxQueryWrapper max(String columnName, String resultName) { + String selectFragment = InfluxDbSqlConstant.MAX + + InfluxDbSqlConstant.LBK + + InfluxDbSqlConstant.DQM + + columnName + + InfluxDbSqlConstant.DQM + + InfluxDbSqlConstant.RBK + + InfluxDbSqlConstant.AS + resultName + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } + /*** + * 批量获取指定字段最大值 + * @author hongawen + * @param prefix 表字段名 + * @param suffix 映射名称 + * @return InfluxQueryWrapper + * 输出 MAX(prefix+diffContent+suffix) as prefix+diffContent+suffix + */ + public InfluxQueryWrapper maxSamePrefixAndSuffix(String prefix, String suffix, List diffContent) { + if (CollectionUtil.isEmpty(diffContent)) { + throw new RuntimeException("查询数值集合为空,请校验!"); + } + for (Object obj : diffContent) { + String fieldName = prefix + obj + suffix; + this.max(fieldName, fieldName); + } + return this; + } + /*** * 获取指定字段最小值 * @author hongawen @@ -368,7 +519,7 @@ public class InfluxQueryWrapper { * 输出 MIN("columnName") */ public InfluxQueryWrapper min(ICFunction columnName) { - return min(columnName, "value"); + return min(columnName, columnName); } /*** @@ -379,7 +530,7 @@ public class InfluxQueryWrapper { * @return InfluxQueryWrapper * 输出 MIN("columnName") as resultName */ - public InfluxQueryWrapper min(ICFunction columnName, String resultName) { + public InfluxQueryWrapper min(ICFunction columnName, ICFunction resultName) { String selectFragment = InfluxDbSqlConstant.MIN + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + @@ -387,12 +538,53 @@ public class InfluxQueryWrapper { InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + + StrPool.C_SPACE; + selectColumns.add(selectFragment); + return this; + } + + /*** + * 获取指定字段最小值 + * @author hongawen + * @param columnName 表字段名 + * @param resultName 映射名称 + * @return InfluxQueryWrapper + * 输出 MAX("columnName") as resultName + */ + public InfluxQueryWrapper min(String columnName, String resultName) { + String selectFragment = InfluxDbSqlConstant.MAX + + InfluxDbSqlConstant.LBK + + InfluxDbSqlConstant.DQM + + columnName + + InfluxDbSqlConstant.DQM + + InfluxDbSqlConstant.RBK + + InfluxDbSqlConstant.AS + resultName + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } + /*** + * 批量获取指定字段最小值 + * @author hongawen + * @param prefix 表字段名 + * @param suffix 映射名称 + * @return InfluxQueryWrapper + * 输出 MIN(prefix+diffContent+suffix) as prefix+diffContent+suffix + */ + public InfluxQueryWrapper minSamePrefixAndSuffix(String prefix, String suffix, List diffContent) { + if (CollectionUtil.isEmpty(diffContent)) { + throw new RuntimeException("查询数值集合为空,请校验!"); + } + for (Object obj : diffContent) { + String fieldName = prefix + obj + suffix; + this.min(fieldName, fieldName); + } + return this; + } + /*** * 返回field key较大的百分之N的值。 * @author hongawen @@ -402,7 +594,7 @@ public class InfluxQueryWrapper { * 输出 PERCENTILE("columnName",95) */ public InfluxQueryWrapper percentile(ICFunction columnName, int percent) { - return percentile(columnName, "value", percent); + return percentile(columnName, columnName, percent); } /*** @@ -414,7 +606,7 @@ public class InfluxQueryWrapper { * @return InfluxQueryWrapper * 输出 PERCENTILE("columnName",95) as resultName */ - public InfluxQueryWrapper percentile(ICFunction columnName, String resultName, int percent) { + public InfluxQueryWrapper percentile(ICFunction columnName, ICFunction resultName, int percent) { String selectFragment = InfluxDbSqlConstant.PERCENTILE + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + @@ -424,7 +616,7 @@ public class InfluxQueryWrapper { percent + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + - resultName + + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; @@ -497,6 +689,30 @@ public class InfluxQueryWrapper { return this; } + /*** + * 指定字段不等于某个值 + * @author hongawen + * @param columnName 表字段名 + * @param columnValue 数值 + * @return InfluxQueryWrapper + * 输出 columnName != columnValue + */ + public InfluxQueryWrapper ne(ICFunction columnName, Object columnValue) { + StringBuilder selectFragment = new StringBuilder(); + selectFragment.append(this.getColumnName(measurement, LambdaUtil.columnToString(columnName))) + .append(InfluxDbSqlConstant.NE); + if (columnValue instanceof String) { + //需要用单引号包装下 + selectFragment.append(InfluxDbSqlConstant.QM) + .append(columnValue) + .append(InfluxDbSqlConstant.QM); + } else { + selectFragment.append(columnValue); + } + conditions.add(selectFragment.toString()); + return this; + } + /*** * 指定字段大于某个值 @@ -598,6 +814,64 @@ public class InfluxQueryWrapper { return this; } + /*** + * 查询条件有多个选项时,效果等同于关系型数据库的in,同时or的内容如果超过100个选项时 + * 会带来严重的性能问题,查询很慢 + * @author hongawen + * @param fieldName 表字段名 + * @param columnValues 数值集合 + * @return InfluxQueryWrapper + * 输出 (columnName = columnValue or columnName = columnValue or columnName = columnValue ) + */ + public InfluxQueryWrapper or(ICFunction fieldName, List columnValues) { + if (CollectionUtil.isEmpty(columnValues)) { + throw new RuntimeException("查询数值集合为空,请校验!"); + } + String columnName = this.getColumnName(measurement, LambdaUtil.columnToString(fieldName)); + List orConditionList = new ArrayList<>(); + for (Object columnValue : columnValues) { + String selectConditionFragment = columnName + InfluxDbSqlConstant.EQ; + if (columnValue instanceof String) { + //需要用单引号包装下 + selectConditionFragment = selectConditionFragment + + InfluxDbSqlConstant.QM + + columnValue + + InfluxDbSqlConstant.QM; + } else { + selectConditionFragment = selectConditionFragment + columnValue; + } + orConditionList.add(selectConditionFragment); + } + String conditionSql = InfluxDbSqlConstant.LBK + + String.join(InfluxDbSqlConstant.OR, orConditionList) + + InfluxDbSqlConstant.RBK; + conditions.add(conditionSql); + return this; + } + + /*** + * 查询条件有多个选项时,效果等同于关系型数据库的in,同时or的内容如果超过100个选项时 + * 会带来严重的性能问题,查询很慢 + * @author hongawen + * @param fieldName 表字段名 + * @param columnValues 数值集合 + * @return InfluxQueryWrapper + * 输出 columnName=正则表达式 + */ + public InfluxQueryWrapper regular(ICFunction fieldName, List columnValues) { + if (CollectionUtil.isEmpty(columnValues)) { + throw new RuntimeException("查询数值集合为空,请校验!"); + } + String columnName = this.getColumnName(measurement, LambdaUtil.columnToString(fieldName)); + String conditionSql = columnName + InfluxDbSqlConstant.EQ; + String middleSql = String.join(InfluxDbSqlConstant.REGULAR_MIDDLE, columnValues); + conditionSql = conditionSql + InfluxDbSqlConstant.REGULAR_PREFIX + + middleSql + + InfluxDbSqlConstant.REGULAR_SUFFIX; + conditions.add(conditionSql); + return this; + } + /********************* [WHERE_clause] [GROUP_BY_clause] [ORDER_BY_clause] [LIMIT_clause] [OFFSET_clause] [SLIMIT_clause] [SOFFSET_clause]*********************/ @@ -660,7 +934,7 @@ public class InfluxQueryWrapper { sqlSelect.append(String.join(StrPool.COMMA, selectColumns)) .append(InfluxDbSqlConstant.FROM) .append(InfluxDbSqlConstant.DQM) - .append( ((Measurement) measurement.getAnnotation(Measurement.class)).name()) + .append(((Measurement) measurement.getAnnotation(Measurement.class)).name()) .append(InfluxDbSqlConstant.DQM); }