package com.njcn.influx.query; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.text.StrPool; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import com.njcn.influx.constant.InfluxDbSqlConstant; import com.njcn.influx.support.ICFunction; import com.njcn.influx.utils.LambdaUtil; import lombok.Data; import org.influxdb.annotation.Column; import org.influxdb.annotation.Measurement; import java.lang.reflect.Field; import java.util.*; /** * @author hongawen * @version 1.0.0 */ @Data public class InfluxQueryWrapper { /*** * 组装后的查询语句 */ private final StringBuilder sqlSelect = new StringBuilder(); /*** * 需要返回的字段 */ private final List selectColumns = new ArrayList<>(); /*** * 查询条件字段 */ private final List conditions = new ArrayList<>(); /*** * 分组集合 */ private final List groupColumn = new ArrayList<>(); /*** * 排序集合 */ private final List orderColumn = new ArrayList<>(); /*** * LIMIT 子句,返回查询结果的前N条points */ private String limitSql = ""; /*** * 查询目标表 */ private Class measurement; /*** * 不确定查询表名时,动态指定 */ private String measurementName; /*** * 返回映射实体 */ private Class resultEntity; /*** * 返回和查询用的同一个实体 * @param measurement 查询目标表 */ public InfluxQueryWrapper(Class measurement) { this.measurement = measurement; this.resultEntity = measurement; this.initSql(); } /*** * 返回和查询用的不是同一个实体 * @param measurement 查询目标表 * @param resultEntity 返回映射实体 */ public InfluxQueryWrapper(Class measurement, Class resultEntity) { this.measurement = measurement; this.resultEntity = resultEntity; this.initSql(); } /*** * 返回和查询用的不是同一个实体 * 注意:该构建方法查询的参数必须使用string传递,禁止lambda传递 * @param measurement 查询目标表 * @param resultEntity 返回映射实体 */ public InfluxQueryWrapper(String measurement, Class resultEntity) { this.measurementName = measurement; this.measurement = null; this.resultEntity = resultEntity; this.initSql(); } /*** * 初始化查询语句 */ public void initSql() { this.selectColumns.clear(); this.conditions.clear(); this.groupColumn.clear(); this.orderColumn.clear(); } /*** * 查询的结果属性 * @author hongawen * @param fieldsStr 属性值 * 输出为 select ["influxColumn" as fieldStr]的形式 */ @SafeVarargs public final InfluxQueryWrapper select(ICFunction... fieldsStr) { if (ArrayUtil.isNotEmpty(fieldsStr)) { StringBuilder selectFragment = new StringBuilder(); Arrays.stream(fieldsStr).forEach(fieldStr -> { selectFragment.setLength(0); selectFragment.append(StrPool.C_SPACE) .append(this.getColumnName(resultEntity, LambdaUtil.columnToString(fieldStr))) .append(StrPool.C_SPACE) .append(InfluxDbSqlConstant.AS) .append(StrPool.C_SPACE) .append(this.getColumnName(resultEntity, LambdaUtil.columnToString(fieldStr))) .append(StrPool.C_SPACE); selectColumns.add(selectFragment.toString()); }); } return this; } public InfluxQueryWrapper select(String columnName, String resultColumnName) { StringBuilder selectFragment = new StringBuilder(); selectFragment.append(StrPool.C_SPACE) .append(columnName) .append(StrPool.C_SPACE) .append(InfluxDbSqlConstant.AS) .append(StrPool.C_SPACE) .append(resultColumnName) .append(StrPool.C_SPACE); selectColumns.add(selectFragment + ""); return this; } // /*** // * 查询的结果属性 // * @author hongawen // * @param fieldsStr 属性值 // * 输出为 select ["influxColumn" as fieldStr]的形式 // */ // @SafeVarargs // public InfluxQueryWrapper select(String... fieldsStr) { // if (ArrayUtil.isNotEmpty(fieldsStr)) { // StringBuilder selectFragment = new StringBuilder(); // Arrays.stream(fieldsStr).forEach(fieldStr -> { // selectFragment.setLength(0); // selectFragment.append(StrPool.C_SPACE) // .append(fieldStr) // .append(StrPool.C_SPACE) // .append(InfluxDbSqlConstant.AS) // .append(StrPool.C_SPACE) // .append(this.getColumnName(resultEntity, LambdaUtil.columnToString(fieldStr))) // .append(StrPool.C_SPACE); // selectColumns.add(selectFragment.toString()); // }); // } // return this; // } /************常见的简单函数处理比如max/min/mean/percentile****************/ /*** * * @author hongawen * @param functionName 指定函数 max min mean等 * @param columnName 表字段名 * @param resultName 映射名 * @return InfluxQueryWrapper */ public InfluxQueryWrapper functionByCustom(String functionName, String columnName, String resultName) { return this; } /*** * 统计记录数 * @author hongawen * @param columnName 表字段名 * @return 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)) + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } public InfluxQueryWrapper count(String columnName) { String selectFragment = InfluxDbSqlConstant.COUNT + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + columnName + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + columnName + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } /*** * 统计平均值 * @author hongawen * @param columnName 表字段名 * @return 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)) + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } public InfluxQueryWrapper mean(String columnName) { String selectFragment = InfluxDbSqlConstant.AVG + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + columnName + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + columnName + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } public InfluxQueryWrapper mean(String columnName,String resultName) { String selectFragment = InfluxDbSqlConstant.AVG + 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 * 输出 mean(prefix+diffContent+suffix) as prefix+diffContent+suffix */ public InfluxQueryWrapper meanSamePrefixAndSuffix(String prefix, String suffix, List diffContent) { if (CollectionUtil.isEmpty(diffContent)) { throw new RuntimeException("查询数值集合为空,请校验!"); } for (Object obj : diffContent) { String fieldName = prefix + obj + suffix; this.mean(fieldName); } return this; } /*** * 统计中位数 * @author hongawen * @param columnName 表字段名 * @return 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 + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } public InfluxQueryWrapper median(String columnName) { String selectFragment = InfluxDbSqlConstant.MEDIAN + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + columnName + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + columnName + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } /*** * 统计指定字段的最常出现的值 * @author hongawen * @param columnName 表字段名 * @return 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 + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } public InfluxQueryWrapper mode(String columnName) { String selectFragment = InfluxDbSqlConstant.MODE + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + columnName + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + columnName + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } /*** * 统计指定字段最大值和最小值的差 * @author hongawen * @param columnName 表字段名 * @return 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 + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } public InfluxQueryWrapper spread(String columnName) { String selectFragment = InfluxDbSqlConstant.SPREAD + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + columnName + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + columnName + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } /*** * 统计指定字段值求和 * @author hongawen * @param columnName 表字段名 * @return 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 + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } public InfluxQueryWrapper sum(String columnName) { String selectFragment = InfluxDbSqlConstant.SUM + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + this.getColumnName(measurement, columnName) + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + this.getColumnName(resultEntity, columnName) + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } /*** * 获取指定字段最大值的集合 * @author hongawen * @param columnName 表字段名 * @return InfluxQueryWrapper * 输出TOP("columnName",number) */ public InfluxQueryWrapper top(ICFunction columnName, int num) { String selectFragment = InfluxDbSqlConstant.TOP + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + this.getColumnName(measurement, LambdaUtil.columnToString(columnName)) + InfluxDbSqlConstant.DQM + StrPool.COMMA + num + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + this.getColumnName(resultEntity, LambdaUtil.columnToString(columnName)) + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } public InfluxQueryWrapper top(String columnName, int num) { String selectFragment = InfluxDbSqlConstant.TOP + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + columnName + InfluxDbSqlConstant.DQM + StrPool.COMMA + num + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + columnName + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } /*** * 获取指定字段最小值的集合 * @author hongawen * @param columnName 表字段名 * @return InfluxQueryWrapper * 输出BOTTOM("columnName",number) */ public InfluxQueryWrapper bottom(ICFunction columnName, int num) { String selectFragment = InfluxDbSqlConstant.BOTTOM + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + this.getColumnName(measurement, LambdaUtil.columnToString(columnName)) + InfluxDbSqlConstant.DQM + StrPool.COMMA + num + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + this.getColumnName(resultEntity, LambdaUtil.columnToString(columnName)) + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } public InfluxQueryWrapper bottom(String columnName, int num) { String selectFragment = InfluxDbSqlConstant.BOTTOM + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + columnName + InfluxDbSqlConstant.DQM + StrPool.COMMA + num + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + columnName + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } /*** * 注:该函数还需调研,暂时不要用 * 统计指定字段邻近值的变化率 * @author hongawen * @param columnName 表字段名 * @return InfluxQueryWrapper * 输出DERIVATIVE("columnName") */ @Deprecated public InfluxQueryWrapper derivative(ICFunction columnName) { String selectFragment = InfluxDbSqlConstant.DERIVATIVE + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + this.getColumnName(measurement, LambdaUtil.columnToString(columnName)) + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS_VALUE; selectColumns.add(selectFragment); return this; } @Deprecated public InfluxQueryWrapper derivative(String columnName) { String selectFragment = InfluxDbSqlConstant.DERIVATIVE + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + columnName + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS_VALUE; selectColumns.add(selectFragment); return this; } /*** * 统计指定字段值时间戳最近的值 * @author hongawen * @param columnName 表字段名 * @return InfluxQueryWrapper * 输出LAST("columnName") */ public InfluxQueryWrapper last(ICFunction columnName) { String selectFragment = InfluxDbSqlConstant.LAST + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + this.getColumnName(measurement, LambdaUtil.columnToString(columnName)) + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS_VALUE; selectColumns.add(selectFragment); return this; } public InfluxQueryWrapper last(String columnName) { String selectFragment = InfluxDbSqlConstant.LAST + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + columnName + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS_VALUE; selectColumns.add(selectFragment); return this; } public InfluxQueryWrapper last(String columnName, String resultName) { String selectFragment = InfluxDbSqlConstant.LAST + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + columnName + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + resultName + StrPool.C_SPACE; ; selectColumns.add(selectFragment); 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; } public InfluxQueryWrapper abs(String columnName) { String selectFragment = InfluxDbSqlConstant.ABS + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + columnName + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + columnName + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } /*** * 获取指定字段最大值 * @author hongawen * @param columnName 表字段名 * @return InfluxQueryWrapper * 输出 MAX("columnName") */ public InfluxQueryWrapper max(ICFunction columnName) { return max(columnName, columnName); } /*** * 获取指定字段最大值 * @author hongawen * @param columnName 表字段名 * @param resultName 映射名称 * @return InfluxQueryWrapper * 输出 MAX("columnName") as resultName */ public InfluxQueryWrapper max(ICFunction columnName, ICFunction resultName) { String selectFragment = InfluxDbSqlConstant.MAX + 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; } public InfluxQueryWrapper max(String columnName) { String selectFragment = InfluxDbSqlConstant.MAX + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + columnName + InfluxDbSqlConstant.DQM + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + columnName + 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 * @param columnName 表字段名 * @return InfluxQueryWrapper * 输出 MIN("columnName") */ public InfluxQueryWrapper min(ICFunction columnName) { return min(columnName, columnName); } /*** * 获取指定字段最小值 * @author hongawen * @param columnName 表字段名 * @param resultName 映射名称 * @return InfluxQueryWrapper * 输出 MIN("columnName") as resultName */ public InfluxQueryWrapper min(ICFunction columnName, ICFunction resultName) { String selectFragment = InfluxDbSqlConstant.MIN + 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; } /*** * 获取指定字段最小值 * @author hongawen * @param columnName 表字段名 * @param resultName 映射名称 * @return InfluxQueryWrapper * 输出 MIN("columnName") as resultName */ public InfluxQueryWrapper min(String columnName, String resultName) { String selectFragment = InfluxDbSqlConstant.MIN + 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 * @param columnName 表字段名 * @param percent 百分之percent * @return InfluxQueryWrapper * 输出 PERCENTILE("columnName",95) */ public InfluxQueryWrapper percentile(ICFunction columnName, int percent) { return percentile(columnName, columnName, percent); } /*** * 返回field key较大的百分之N的值。 * @author hongawen * @param columnName 表字段名 * @param resultName 映射名称 * @param percent 百分之percent * @return InfluxQueryWrapper * 输出 PERCENTILE("columnName",95) as resultName */ public InfluxQueryWrapper percentile(ICFunction columnName, ICFunction resultName, int percent) { String selectFragment = InfluxDbSqlConstant.PERCENTILE + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + this.getColumnName(measurement, LambdaUtil.columnToString(columnName)) + InfluxDbSqlConstant.DQM + StrPool.COMMA + percent + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + this.getColumnName(resultEntity, LambdaUtil.columnToString(resultName)) + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } public InfluxQueryWrapper percentile(String columnName, int percent) { String selectFragment = InfluxDbSqlConstant.PERCENTILE + InfluxDbSqlConstant.LBK + InfluxDbSqlConstant.DQM + columnName + InfluxDbSqlConstant.DQM + StrPool.COMMA + percent + InfluxDbSqlConstant.RBK + InfluxDbSqlConstant.AS + columnName + StrPool.C_SPACE; selectColumns.add(selectFragment); return this; } /**************************自定义查询条件,比如between、>、<、=、>=、<=等等**************************/ /*** * 注:influxdb * 在WHERE子句中单引号来表示字符串字段值。具有无引号字符串字段值或双引号字符串字段值的查询将不会返回任何数据 * ,并且在大多数情况下也不会返回错误。 * @author hongawen * @param fieldName 字段名 * @param val1 起始值 * @param val2 结束值 * @return InfluxQueryWrapper * 输出为:time >='2022-04-30 16:00:00' AND time <='2022-05-30 16:00:00' */ public InfluxQueryWrapper between(ICFunction fieldName, Object val1, Object val2) { StringBuilder selectFragment = new StringBuilder(); String columnName = this.getColumnName(measurement, LambdaUtil.columnToString(fieldName)); selectFragment.append(StrPool.C_SPACE) .append(columnName) .append(InfluxDbSqlConstant.GE); if (val1 instanceof String) { //需要用单引号包装下 selectFragment.append(InfluxDbSqlConstant.QM) .append(val1) .append(InfluxDbSqlConstant.QM) .append(InfluxDbSqlConstant.AND) .append(columnName) .append(InfluxDbSqlConstant.LE) .append(InfluxDbSqlConstant.QM) .append(val2) .append(InfluxDbSqlConstant.QM); } else { selectFragment.append(val1) .append(InfluxDbSqlConstant.AND) .append(columnName) .append(InfluxDbSqlConstant.LE) .append(val2); } this.conditions.add(selectFragment.toString()); return this; } public InfluxQueryWrapper between(String fieldName, Object val1, Object val2) { StringBuilder selectFragment = new StringBuilder(); selectFragment.append(StrPool.C_SPACE) .append(fieldName) .append(InfluxDbSqlConstant.GE); if (val1 instanceof String) { //需要用单引号包装下 selectFragment.append(InfluxDbSqlConstant.QM) .append(val1) .append(InfluxDbSqlConstant.QM) .append(InfluxDbSqlConstant.AND) .append(fieldName) .append(InfluxDbSqlConstant.LE) .append(InfluxDbSqlConstant.QM) .append(val2) .append(InfluxDbSqlConstant.QM); } else { selectFragment.append(val1) .append(InfluxDbSqlConstant.AND) .append(fieldName) .append(InfluxDbSqlConstant.LE) .append(val2); } this.conditions.add(selectFragment.toString()); return this; } /*** * 指定字段等于某个值 * @author hongawen * @param columnName 表字段名 * @param columnValue 数值 * @return InfluxQueryWrapper * 输出 columnName = columnValue */ public InfluxQueryWrapper eq(ICFunction columnName, Object columnValue) { StringBuilder selectFragment = new StringBuilder(); selectFragment.append(this.getColumnName(measurement, LambdaUtil.columnToString(columnName))) .append(InfluxDbSqlConstant.EQ); if (columnValue instanceof String) { //需要用单引号包装下 selectFragment.append(InfluxDbSqlConstant.QM) .append(columnValue) .append(InfluxDbSqlConstant.QM); } else { selectFragment.append(columnValue); } conditions.add(selectFragment.toString()); return this; } public InfluxQueryWrapper eq(String columnName, Object columnValue) { StringBuilder selectFragment = new StringBuilder(); selectFragment.append(columnName) .append(InfluxDbSqlConstant.EQ); if (columnValue instanceof String) { //需要用单引号包装下 selectFragment.append(InfluxDbSqlConstant.QM) .append(columnValue) .append(InfluxDbSqlConstant.QM); } else { selectFragment.append(columnValue); } conditions.add(selectFragment.toString()); 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; } public InfluxQueryWrapper ne(String columnName, Object columnValue) { StringBuilder selectFragment = new StringBuilder(); selectFragment.append(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; } /*** * 指定字段大于某个值 * @author hongawen * @param fieldName 表字段名 * @param columnValue 数值 * @return InfluxQueryWrapper * 输出 columnName > columnValue */ public InfluxQueryWrapper gt(ICFunction fieldName, Object columnValue) { StringBuilder selectFragment = new StringBuilder(); String columnName = this.getColumnName(measurement, LambdaUtil.columnToString(fieldName)); selectFragment.append(columnName) .append(InfluxDbSqlConstant.GT); if (columnValue instanceof String) { //需要用单引号包装下 selectFragment.append(InfluxDbSqlConstant.QM) .append(columnValue) .append(InfluxDbSqlConstant.QM); } else { selectFragment.append(columnValue); } conditions.add(selectFragment.toString()); return this; } public InfluxQueryWrapper gt(String columnName, Object columnValue) { StringBuilder selectFragment = new StringBuilder(); selectFragment.append(columnName) .append(InfluxDbSqlConstant.GT); if (columnValue instanceof String) { //需要用单引号包装下 selectFragment.append(InfluxDbSqlConstant.QM) .append(columnValue) .append(InfluxDbSqlConstant.QM); } else { selectFragment.append(columnValue); } conditions.add(selectFragment.toString()); return this; } /*** * 指定字段大于等于某个值 * @author hongawen * @param fieldName 表字段名 * @param columnValue 数值 * @return InfluxQueryWrapper * 输出 columnName >= columnValue */ public InfluxQueryWrapper ge(ICFunction fieldName, Object columnValue) { StringBuilder selectFragment = new StringBuilder(); String columnName = this.getColumnName(measurement, LambdaUtil.columnToString(fieldName)); selectFragment.append(columnName) .append(InfluxDbSqlConstant.GE); if (columnValue instanceof String) { //需要用单引号包装下 selectFragment.append(InfluxDbSqlConstant.QM) .append(columnValue) .append(InfluxDbSqlConstant.QM); } else { selectFragment.append(columnValue); } conditions.add(selectFragment.toString()); return this; } public InfluxQueryWrapper ge(String columnName, Object columnValue) { StringBuilder selectFragment = new StringBuilder(); selectFragment.append(columnName) .append(InfluxDbSqlConstant.GE); if (columnValue instanceof String) { //需要用单引号包装下 selectFragment.append(InfluxDbSqlConstant.QM) .append(columnValue) .append(InfluxDbSqlConstant.QM); } else { selectFragment.append(columnValue); } conditions.add(selectFragment.toString()); return this; } /*** * 指定字段小于某个值 * @author hongawen * @param columnName 表字段名 * @param columnValue 数值 * @return InfluxQueryWrapper * 输出 columnName < columnValue */ public InfluxQueryWrapper lt(String columnName, Object columnValue) { StringBuilder selectFragment = new StringBuilder(); selectFragment.append(columnName) .append(InfluxDbSqlConstant.LT); if (columnValue instanceof String) { //需要用单引号包装下 selectFragment.append(InfluxDbSqlConstant.QM) .append(columnValue) .append(InfluxDbSqlConstant.QM); } else { selectFragment.append(columnValue); } conditions.add(selectFragment.toString()); return this; } /*** * 指定字段小于等于某个值 * @author hongawen * @param fieldName 表字段名 * @param columnValue 数值 * @return InfluxQueryWrapper * 输出 columnName <= columnValue */ public InfluxQueryWrapper le(ICFunction fieldName, Object columnValue) { StringBuilder selectFragment = new StringBuilder(); String columnName = this.getColumnName(measurement, LambdaUtil.columnToString(fieldName)); selectFragment.append(columnName) .append(InfluxDbSqlConstant.LE); if (columnValue instanceof String) { //需要用单引号包装下 selectFragment.append(InfluxDbSqlConstant.QM) .append(columnValue) .append(InfluxDbSqlConstant.QM); } else { selectFragment.append(columnValue); } conditions.add(selectFragment.toString()); return this; } public InfluxQueryWrapper le(String columnName, Object columnValue) { StringBuilder selectFragment = new StringBuilder(); selectFragment.append(columnName) .append(InfluxDbSqlConstant.LE); if (columnValue instanceof String) { //需要用单引号包装下 selectFragment.append(InfluxDbSqlConstant.QM) .append(columnValue) .append(InfluxDbSqlConstant.QM); } else { selectFragment.append(columnValue); } conditions.add(selectFragment.toString()); 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 (O 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; } public InfluxQueryWrapper or(String columnName, List columnValues) { if (CollectionUtil.isEmpty(columnValues)) { throw new RuntimeException("查询数值集合为空,请校验!"); } List orConditionList = new ArrayList<>(); for (O 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; } /*** * @author hongawen * @param fieldName 表字段名 * @param columnValues 数值集合 * @return InfluxQueryWrapper * 输出 columnName=正则表达式 */ public InfluxQueryWrapper regular(ICFunction fieldName, String columnValues) { if (StrUtil.isEmpty(columnValues)) { throw new RuntimeException("查询数值为空,请校验!"); } String columnName = this.getColumnName(measurement, LambdaUtil.columnToString(fieldName)); String conditionSql = columnName + InfluxDbSqlConstant.EQ; conditionSql = conditionSql + InfluxDbSqlConstant.REGULAR_PREFIX + columnValues + InfluxDbSqlConstant.REGULAR_SUFFIX; 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]*********************/ /*** * 指定字段分组 * @author hongawen * @param columnName 表字段名 * @return InfluxQueryWrapper * 输出 columnName */ @SafeVarargs public final InfluxQueryWrapper groupBy(ICFunction... columnName) { for (ICFunction tricFunction : columnName) { groupColumn.add(this.getColumnName(measurement, LambdaUtil.columnToString(tricFunction))); } return this; } public final InfluxQueryWrapper groupBy(String columnName) { groupColumn.add(columnName); return this; } /*** * 指定字段降序 * @author hongawen * @return InfluxQueryWrapper * 输出 time desc */ public InfluxQueryWrapper timeDesc() { String selectFragment = InfluxDbSqlConstant.TIME + InfluxDbSqlConstant.DESC; orderColumn.add(selectFragment); return this; } /*** * 指定字段升序 * @author hongawen * @return InfluxQueryWrapper * 输出 time asc */ public InfluxQueryWrapper timeAsc() { String selectFragment = InfluxDbSqlConstant.TIME + InfluxDbSqlConstant.ASC; orderColumn.add(selectFragment); return this; } /*** * LIMIT 子句,返回查询结果的前N条points * @author hongawen * @return InfluxQueryWrapper * 输出 limit 10 */ public InfluxQueryWrapper limit(int limit) { limitSql = InfluxDbSqlConstant.LIMIT + limit; return this; } /*** * 根据配置后的实体生成对应的sql * @author hongawen * @return String 最终查询的sql语句 */ public String generateSql() { this.sqlSelect.setLength(0); this.sqlSelect.append(InfluxDbSqlConstant.SELECT); //判断用户需要返回的属性 if (CollectionUtil.isEmpty(selectColumns)) { sqlSelect.append(InfluxDbSqlConstant.ALL) .append(InfluxDbSqlConstant.FROM) .append(InfluxDbSqlConstant.DQM); if (Objects.isNull(this.measurement)) { sqlSelect.append(measurementName) .append(InfluxDbSqlConstant.DQM); } else { sqlSelect.append(((Measurement) measurement.getAnnotation(Measurement.class)).name()) .append(InfluxDbSqlConstant.DQM); } } else { //将集合处理成查询属性 sqlSelect.append(String.join(StrPool.COMMA, selectColumns)) .append(InfluxDbSqlConstant.FROM) .append(InfluxDbSqlConstant.DQM); if (Objects.isNull(this.measurement)) { sqlSelect.append(measurementName) .append(InfluxDbSqlConstant.DQM); } else { sqlSelect.append(((Measurement) measurement.getAnnotation(Measurement.class)).name()) .append(InfluxDbSqlConstant.DQM); } } //判断是否有查询条件 if (CollectionUtil.isNotEmpty(conditions)) { sqlSelect.append(InfluxDbSqlConstant.WHERE) .append(String.join(InfluxDbSqlConstant.AND, conditions)); } //判断是否有分组 if (CollectionUtil.isNotEmpty(groupColumn)) { sqlSelect.append(InfluxDbSqlConstant.GB) .append(String.join(StrPool.COMMA, groupColumn)); } //判断是否有排序 if (CollectionUtil.isNotEmpty(orderColumn)) { sqlSelect.append(InfluxDbSqlConstant.OB) .append(String.join(StrPool.COMMA, orderColumn)); } //判断是否有limit子句 if(StrUtil.isNotBlank(limitSql)){ sqlSelect.append(limitSql); } //最后拼接上时区 sqlSelect.append(InfluxDbSqlConstant.TZ); return sqlSelect.toString(); } /*** * * @author hongawen * @param beanClass 实体类 * @param fieldName 属性名 * @return Field 属性 */ private Field getTargetClassField(Class beanClass, String fieldName) { Field field = ReflectUtil.getField(beanClass, fieldName); if (Objects.isNull(field)) { throw new RuntimeException(fieldName + "在目标实体类中不存在!!!"); } return field; } /*** * 获取sql拼接的名称,存在注解名就用注解名,否则就用属性名 * @author hongawen * @param clazz 类型 * @param fieldName 属性名 * @return String */ private String getColumnName(Class clazz, String fieldName) { Field field = this.getTargetClassField(clazz, fieldName); return getColumnName(field); } /*** * 获取sql拼接的名称,存在注解名就用注解名,否则就用属性名 * @author hongawen * @return String */ public static String getColumnName(Field field) { Column column = field.getAnnotation(Column.class); //数据库字段 String influxColumn; if (Objects.isNull(column)) { //没有注解,就用属性名 influxColumn = field.getName(); } else { //获取注解映射的名称 influxColumn = column.name(); } return influxColumn; } }