【功能优化】IoT:清理通用 TDengine 封装,使用 SQL 查询
This commit is contained in:
parent
8089f3a319
commit
b319485ca6
|
@ -1,85 +0,0 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
|
||||
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelRespVO;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
/**
|
||||
* FieldParser 类用于解析和转换物模型字段到 TDengine 字段
|
||||
*/
|
||||
public class FieldParser {
|
||||
|
||||
/**
|
||||
* 物模型到td数据类型映射
|
||||
*/
|
||||
@Deprecated
|
||||
private static final HashMap<String, String> TYPE_MAPPING = new HashMap<>() {
|
||||
{
|
||||
put("INT", "INT");
|
||||
put("FLOAT", "FLOAT");
|
||||
put("DOUBLE", "DOUBLE");
|
||||
put("BOOL", "BOOL");
|
||||
put("ENUM", "NCHAR");
|
||||
put("TEXT", "NCHAR");
|
||||
put("DATE", "NCHAR");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 将物模型字段转换为td字段
|
||||
*
|
||||
* @param property 物模型属性
|
||||
* @return TdField对象
|
||||
*/
|
||||
public static TdFieldDO parse(ThingModelProperty property) {
|
||||
// 将物模型字段类型映射为 td 字段类型
|
||||
String fieldName = property.getIdentifier().toLowerCase();
|
||||
String fType = TYPE_MAPPING.get(property.getDataType().toUpperCase());
|
||||
// 如果字段类型为NCHAR,默认长度为64
|
||||
int dataLength = 0;
|
||||
if ("NCHAR".equals(fType)) {
|
||||
dataLength = 64;
|
||||
}
|
||||
return new TdFieldDO(fieldName, fType, dataLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从物模型中获取字段列表
|
||||
*
|
||||
* @param thingModel 物模型响应对象
|
||||
* @return 字段列表
|
||||
*/
|
||||
public static List<TdFieldDO> parse(ThingModelRespVO thingModel) {
|
||||
return convertList(thingModel.getModel().getProperties(), FieldParser::parse);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将从库中查出来的字段信息转换为 TDengine 字段对象
|
||||
*
|
||||
* @param rows 从库中查出的字段信息列表
|
||||
* @return 转换后的 TDengine 字段对象列表
|
||||
*/
|
||||
public static List<TdFieldDO> parse(List<List<Object>> rows) {
|
||||
return convertList(rows, row -> {
|
||||
String type = row.get(1).toString().toUpperCase();
|
||||
// TODO @puhui999:"NCHAR" 最好枚举下
|
||||
int dataLength = "NCHAR".equals(type) ? Integer.parseInt(row.get(2).toString()) : -1;
|
||||
return new TdFieldDO(row.get(0).toString(), type, dataLength);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字段字义
|
||||
*/
|
||||
@Deprecated
|
||||
public static String getFieldDefine(TdFieldDO field) {
|
||||
return "`" + field.getFieldName() + "`" + " "
|
||||
+ (field.getDataLength() > 0 ? String.format("%s(%d)", field.getDataType(), field.getDataLength())
|
||||
: field.getDataType());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
// TODO @haohao:类似这个,其实可以参考 mybatis plus,querywrapper,搞个 TdEngineQueryWrapper。这样看起来会更好懂。
|
||||
/**
|
||||
* 查询DO
|
||||
*/
|
||||
@Data
|
||||
@Deprecated
|
||||
public class SelectDO {
|
||||
|
||||
// TODO @haoha:database 是个单词
|
||||
/**
|
||||
* 数据库名称
|
||||
*/
|
||||
private String dataBaseName;
|
||||
|
||||
/**
|
||||
* 超级表名称
|
||||
*/
|
||||
private String tableName;
|
||||
|
||||
/**
|
||||
* 查询字段
|
||||
*/
|
||||
private String fieldName;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
private Long startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
private Long endTime;
|
||||
|
||||
/**
|
||||
* 查询类型
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
private String deviceId;
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* tags查询DO
|
||||
*/
|
||||
@Data
|
||||
@Deprecated
|
||||
public class TagsSelectDO {
|
||||
|
||||
/**
|
||||
* 数据库名称
|
||||
*/
|
||||
private String dataBaseName;
|
||||
|
||||
/**
|
||||
* 超级表名称
|
||||
*/
|
||||
private String stableName;
|
||||
|
||||
/**
|
||||
* tags名称
|
||||
*/
|
||||
private String tagsName;
|
||||
|
||||
/**
|
||||
* tags值
|
||||
*/
|
||||
private Long startTime;
|
||||
|
||||
/**
|
||||
* tags值
|
||||
*/
|
||||
private Long endTime;
|
||||
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
// TODO 芋艿:看看是不是后续简化掉。
|
||||
/**
|
||||
* TD 引擎的字段
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
@Deprecated
|
||||
public class TdFieldDO {
|
||||
|
||||
/**
|
||||
* 字段名称
|
||||
*/
|
||||
private String fieldName;
|
||||
|
||||
/**
|
||||
* 字段类型
|
||||
*/
|
||||
private String dataType;
|
||||
|
||||
/**
|
||||
* 字段长度
|
||||
*/
|
||||
private Integer dataLength = 0;
|
||||
|
||||
/**
|
||||
* 字段值
|
||||
*/
|
||||
private Object fieldValue;
|
||||
|
||||
public TdFieldDO(String fieldName, String dataType, Integer dataLength) {
|
||||
this.fieldName = fieldName;
|
||||
this.dataType = dataType;
|
||||
this.dataLength = dataLength;
|
||||
}
|
||||
|
||||
public TdFieldDO(String fieldName, Object fieldValue) {
|
||||
this.fieldName = fieldName;
|
||||
this.fieldValue = fieldValue;
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TdResponse 类用于处理 TDengine 的响应
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Deprecated
|
||||
public class TdResponse {
|
||||
|
||||
public static final int CODE_SUCCESS = 0;
|
||||
public static final int CODE_TB_NOT_EXIST = 866;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
private int code;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
private String desc;
|
||||
|
||||
/**
|
||||
* 列信息
|
||||
* [["time","TIMESTAMP",8,""],["powerstate","TINYINT",1,""],["brightness","INT",4,""],["deviceid","NCHAR",32,"TAG"]]
|
||||
*/
|
||||
private List data;
|
||||
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
// TODO @haohao:有部分非实体的部分,是不是可以搞到 iot 的 framework 包下,搞个 tdengine 包,作为框架级的封装,放在 dataobject,感觉不是很合理哈。【可以微信讨论下】
|
||||
/**
|
||||
* TdRestApi 类用于处理 TDengine 的 REST API 请求
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@Deprecated // TODO 芋艿:貌似没用到
|
||||
public class TdRestApi {
|
||||
|
||||
@Value("${spring.datasource.dynamic.datasource.tdengine.url}")
|
||||
private String url;
|
||||
|
||||
@Value("${spring.datasource.dynamic.datasource.tdengine.username}")
|
||||
private String username;
|
||||
|
||||
@Value("${spring.datasource.dynamic.datasource.tdengine.password}")
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 获取 REST API URL
|
||||
*/
|
||||
private String getRestApiUrl() {
|
||||
String restUrl = url.replace("jdbc:TAOS-RS://", "")
|
||||
.replaceAll("\\?.*", "");
|
||||
int idx = restUrl.lastIndexOf("/");
|
||||
return String.format("%s/rest/sql/%s", restUrl.substring(0, idx), restUrl.substring(idx + 1));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 新建td api请求对象
|
||||
*/
|
||||
public HttpRequest newApiRequest(String sql) {
|
||||
return HttpRequest
|
||||
.post(getRestApiUrl())
|
||||
.body(sql)
|
||||
.basicAuth(username, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行sql
|
||||
*/
|
||||
public TdResponse execSql(String sql) {
|
||||
log.info("exec td sql:{}", sql);
|
||||
HttpRequest request = newApiRequest(sql);
|
||||
HttpResponse response = request.execute();
|
||||
return JSONUtil.toBean(response.body(), TdResponse.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Deprecated
|
||||
/**
|
||||
* TD 引擎的数据库
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TdTableDO {
|
||||
|
||||
/**
|
||||
* 数据库名称
|
||||
*/
|
||||
private String dataBaseName;
|
||||
|
||||
// TODO @haohao:superTableName 和 tableName 是不是合并。因为每个 mapper 操作的时候,有且只会使用到其中一个。
|
||||
/**
|
||||
* 超级表名称
|
||||
*/
|
||||
private String superTableName;
|
||||
|
||||
/**
|
||||
* 表名称
|
||||
*/
|
||||
private String tableName;
|
||||
|
||||
private String productKey;
|
||||
|
||||
private String deviceKey;
|
||||
|
||||
/**
|
||||
* COLUMN 字段
|
||||
*/
|
||||
private TdFieldDO column;
|
||||
|
||||
/**
|
||||
* TAG 字段
|
||||
*/
|
||||
private TdFieldDO tag;
|
||||
|
||||
/**
|
||||
* COLUMN 字段 - 列表
|
||||
*/
|
||||
private List<TdFieldDO> columns;
|
||||
|
||||
/**
|
||||
* TAG 字段 - 列表
|
||||
*/
|
||||
private List<TdFieldDO> tags;
|
||||
|
||||
public TdTableDO(String dataBaseName, String superTableName, List<TdFieldDO> columns, List<TdFieldDO> tags) {
|
||||
this.dataBaseName = dataBaseName;
|
||||
this.superTableName = superTableName;
|
||||
this.columns = columns;
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public TdTableDO(String dataBaseName, String superTableName) {
|
||||
this.dataBaseName = dataBaseName;
|
||||
this.superTableName = superTableName;
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
// TODO @芋艿:纠结下字段
|
||||
@Deprecated // TODO @super:看看啥时候删除下哈。
|
||||
/**
|
||||
* TD 物模型消息日志的数据库
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ThingModelMessageDO {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 消息 ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 系统扩展参数
|
||||
*
|
||||
* 例如:设备状态、系统时间、固件版本等系统级信息
|
||||
*/
|
||||
private Object system;
|
||||
|
||||
/**
|
||||
* 请求方法
|
||||
*
|
||||
* 例如:thing.event.property.post
|
||||
*/
|
||||
private String method;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
private Object params;
|
||||
|
||||
/**
|
||||
* 属性上报时间戳
|
||||
*/
|
||||
private Long time;
|
||||
|
||||
/**
|
||||
* 设备信息
|
||||
*/
|
||||
private String productKey;
|
||||
|
||||
|
||||
/**
|
||||
* 设备 key
|
||||
*/
|
||||
private String deviceKey;
|
||||
|
||||
}
|
|
@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
|
|||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
|
||||
import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField;
|
||||
import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS;
|
||||
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
||||
|
@ -78,27 +77,6 @@ public interface IotDevicePropertyDataMapper {
|
|||
void alterProductPropertySTableDropField(@Param("productKey") String productKey,
|
||||
@Param("field") TDengineTableField field);
|
||||
|
||||
//TODO:先参考一下老逻辑,后续改进
|
||||
/**
|
||||
* 插入数据 - 指定列插入数据
|
||||
*
|
||||
* @param table 数据
|
||||
* productKey 产品 key
|
||||
* deviceKey 设备 key
|
||||
* columns 列
|
||||
*/
|
||||
void insertDevicePropertyData(TdTableDO table);
|
||||
|
||||
//TODO:先参考一下老逻辑,后续改进
|
||||
/**
|
||||
* 查看超级表 - 获取超级表的结构信息
|
||||
* SQL:DESCRIBE [db_name.]stb_name;
|
||||
*
|
||||
* @param superTable 超级表信息
|
||||
* productKey 产品 key
|
||||
*/
|
||||
List<Map<String, Object>> describeSuperTable(TdTableDO superTable);
|
||||
|
||||
/**
|
||||
* 获取历史数据列表
|
||||
*
|
||||
|
|
|
@ -1,147 +0,0 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.tdengine;
|
||||
|
||||
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 专门处理 DDL(数据定义语言)操作,包含所有的数据库和表的定义操作,例如创建数据库、创建超级表、创建子表等
|
||||
*/
|
||||
@Mapper
|
||||
@DS("tdengine")
|
||||
public interface TdEngineDDLMapper {
|
||||
|
||||
/**
|
||||
* 创建数据库
|
||||
* SQL:CREATE DATABASE [IF NOT EXISTS] db_name [database_options];
|
||||
*
|
||||
* @param dataBaseName 数据库名称
|
||||
*/
|
||||
@TenantIgnore
|
||||
void createDatabase(@Param("dataBaseName") String dataBaseName);
|
||||
|
||||
/**
|
||||
* 创建超级表
|
||||
* SQL:CREATE STABLE [IF NOT EXISTS] stb_name (create_definition [, create_definition] ...) TAGS (create_definition [, create_definition] ...) [table_options];
|
||||
*
|
||||
* @param superTable 超级表信息
|
||||
* dataBaseName 数据库名称
|
||||
* superTableName 超级表名称
|
||||
* columns 列信息
|
||||
* tags 标签信息
|
||||
*/
|
||||
@TenantIgnore
|
||||
void createSuperTable(TdTableDO superTable);
|
||||
|
||||
/**
|
||||
* 查看超级表 - 显示当前数据库下的所有超级表信息
|
||||
* SQL:SHOW STABLES [LIKE tb_name_wildcard];
|
||||
*
|
||||
* @param superTable 超级表信息
|
||||
* dataBaseName 数据库名称
|
||||
* superTableName 超级表名称
|
||||
*/
|
||||
@TenantIgnore
|
||||
List<Map<String, Object>> showSuperTables(TdTableDO superTable);
|
||||
|
||||
/**
|
||||
* 查看超级表 - 获取超级表的结构信息
|
||||
* SQL:DESCRIBE [db_name.]stb_name;
|
||||
*
|
||||
* @param superTable 超级表信息
|
||||
* dataBaseName 数据库名称
|
||||
* superTableName 超级表名称
|
||||
*/
|
||||
@TenantIgnore
|
||||
List<Map<String, Object>> describeSuperTable(TdTableDO superTable);
|
||||
|
||||
/**
|
||||
* 修改超级表 - 增加列
|
||||
* SQL:ALTER STABLE stb_name ADD COLUMN col_name column_type;
|
||||
*
|
||||
* @param superTable 超级表信息
|
||||
* dataBaseName 数据库名称
|
||||
* superTableName 超级表名称
|
||||
* column 列信息
|
||||
*/
|
||||
@TenantIgnore
|
||||
void addColumnForSuperTable(TdTableDO superTable);
|
||||
|
||||
/**
|
||||
* 修改超级表 - 删除列
|
||||
* SQL:ALTER STABLE stb_name DROP COLUMN col_name;
|
||||
*
|
||||
* @param superTable 超级表信息
|
||||
* dataBaseName 数据库名称
|
||||
* superTableName 超级表名称
|
||||
* column 列信息
|
||||
*/
|
||||
@TenantIgnore
|
||||
void dropColumnForSuperTable(TdTableDO superTable);
|
||||
|
||||
/**
|
||||
* 修改超级表 - 修改列宽
|
||||
* SQL:ALTER STABLE stb_name MODIFY COLUMN col_name data_type(length);
|
||||
*
|
||||
* @param superTable 超级表信息
|
||||
* dataBaseName 数据库名称
|
||||
* superTableName 超级表名称
|
||||
* column 列信息
|
||||
*/
|
||||
@TenantIgnore
|
||||
void modifyColumnWidthForSuperTable(TdTableDO superTable);
|
||||
|
||||
/**
|
||||
* 修改超级表 - 为超级表添加标签
|
||||
*
|
||||
* @param superTable 超级表信息
|
||||
* dataBaseName 数据库名称
|
||||
* superTableName 超级表名称
|
||||
* tag 标签信息
|
||||
*/
|
||||
@TenantIgnore
|
||||
void addTagForSuperTable(TdTableDO superTable);
|
||||
|
||||
/**
|
||||
* 修改超级表 - 为超级表删除标签
|
||||
*
|
||||
* @param superTable 超级表信息
|
||||
* dataBaseName 数据库名称
|
||||
* superTableName 超级表名称
|
||||
* tag 标签信息
|
||||
*/
|
||||
@TenantIgnore
|
||||
void dropTagForSuperTable(TdTableDO superTable);
|
||||
|
||||
/**
|
||||
* 创建子表 - 创建子表
|
||||
* SQL:CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...);
|
||||
*
|
||||
* @param table 表信息
|
||||
* dataBaseName 数据库名称
|
||||
* superTableName 超级表名称
|
||||
* tableName 子表名称
|
||||
* tags TAG 字段
|
||||
*/
|
||||
@TenantIgnore
|
||||
void createTable(TdTableDO table);
|
||||
|
||||
/**
|
||||
* 创建子表 - 创建子表并指定标签的值
|
||||
* SQL:CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...);
|
||||
*
|
||||
* @param table 表信息
|
||||
* dataBaseName 数据库名称
|
||||
* superTableName 超级表名称
|
||||
* tableName 子表名称
|
||||
* tags TAG 字段
|
||||
*/
|
||||
@TenantIgnore
|
||||
void createTableWithTags(TdTableDO table);
|
||||
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.tdengine;
|
||||
|
||||
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 专门处理 TD Engine 的 DML(数据操作语言)操作,处理所有的数据查询和写入操作,如插入数据、查询数据等
|
||||
*/
|
||||
@Mapper
|
||||
@DS("tdengine")
|
||||
public interface TdEngineDMLMapper {
|
||||
|
||||
/**
|
||||
* 插入数据 - 指定列插入数据
|
||||
*
|
||||
* @param table 数据
|
||||
* dataBaseName 数据库名
|
||||
* tableName 表名
|
||||
* columns 列
|
||||
*/
|
||||
@TenantIgnore
|
||||
void insertData(TdTableDO table);
|
||||
|
||||
/**
|
||||
* 根据时间戳查询数据
|
||||
*
|
||||
* @param selectDO 查询条件
|
||||
* @return 查询结果列表
|
||||
*/
|
||||
@TenantIgnore
|
||||
List<Map<String, Object>> selectByTimestamp(SelectDO selectDO);
|
||||
|
||||
/**
|
||||
* 根据时间戳获取数据条数
|
||||
*
|
||||
* @param selectDO 查询条件
|
||||
* @return 数据条数
|
||||
*/
|
||||
@TenantIgnore
|
||||
Map<String, Long> selectCountByTimestamp(SelectDO selectDO);
|
||||
|
||||
/**
|
||||
* 获取最新数据
|
||||
*
|
||||
* @param selectDO 查询条件
|
||||
* @return 最新数据
|
||||
*/
|
||||
@TenantIgnore
|
||||
Map<String, Object> selectOneLastData(SelectDO selectDO);
|
||||
|
||||
/**
|
||||
* 获取历史数据列表
|
||||
*
|
||||
* @param selectVisualDO 查询条件
|
||||
* @return 历史数据列表
|
||||
*/
|
||||
@TenantIgnore
|
||||
List<Map<String, Object>> selectHistoryDataList(SelectVisualDO selectVisualDO);
|
||||
|
||||
/**
|
||||
* 获取实时数据列表
|
||||
*
|
||||
* @param selectVisualDO 查询条件
|
||||
* @return 实时数据列表
|
||||
*/
|
||||
@TenantIgnore
|
||||
List<Map<String, Object>> selectRealtimeDataList(SelectVisualDO selectVisualDO);
|
||||
|
||||
/**
|
||||
* 获取聚合数据列表
|
||||
*
|
||||
* @param selectVisualDO 查询条件
|
||||
* @return 聚合数据列表
|
||||
*/
|
||||
@TenantIgnore
|
||||
List<Map<String, Object>> selectAggregateDataList(SelectVisualDO selectVisualDO);
|
||||
|
||||
/**
|
||||
* 根据标签获取最新数据列表
|
||||
*
|
||||
* @param tagsSelectDO 查询条件
|
||||
* @return 最新数据列表
|
||||
*/
|
||||
@TenantIgnore
|
||||
List<Map<String, Object>> selectLastDataListByTags(TagsSelectDO tagsSelectDO);
|
||||
|
||||
/**
|
||||
* 获取历史数据条数
|
||||
*
|
||||
* @param selectVisualDO 查询条件
|
||||
* @return 数据条数
|
||||
*/
|
||||
@TenantIgnore
|
||||
Long selectHistoryCount(SelectVisualDO selectVisualDO);
|
||||
}
|
|
@ -5,17 +5,17 @@ import lombok.RequiredArgsConstructor;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* TDengine 表初始化的 Configuration
|
||||
*
|
||||
* @author alwayssuper
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class TDengineTableInitConfiguration implements ApplicationRunner {
|
||||
@Slf4j
|
||||
public class TDengineTableInitRunner implements ApplicationRunner {
|
||||
|
||||
private final IotDeviceLogService deviceLogService;
|
||||
|
||||
|
@ -26,7 +26,7 @@ public class TDengineTableInitConfiguration implements ApplicationRunner {
|
|||
deviceLogService.defineDeviceLog();
|
||||
} catch (Exception ex) {
|
||||
// 初始化失败时打印错误日志并退出系统
|
||||
log.error("[TDengine] 初始化设备日志表结构失败,系统无法正常运行,即将退出", ex);
|
||||
log.error("[run][TDengine初始化设备日志表结构失败,系统无法正常运行,即将退出]", ex);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDDLMapper">
|
||||
|
||||
<!-- 创建数据库 -->
|
||||
<update id="createDatabase" parameterType="String">
|
||||
CREATE DATABASE IF NOT EXISTS ${dataBaseName}
|
||||
</update>
|
||||
|
||||
<!-- 创建超级表 -->
|
||||
<update id="createSuperTable">
|
||||
CREATE STABLE IF NOT EXISTS ${dataBaseName}.${superTableName}
|
||||
<foreach item="item" collection="columns" separator=","
|
||||
open="(" close=")">
|
||||
${item.fieldName} ${item.dataType}
|
||||
<if test="item.dataLength > 0">
|
||||
(${item.dataLength})
|
||||
</if>
|
||||
</foreach>
|
||||
TAGS
|
||||
<foreach item="item" collection="tags" separator=","
|
||||
open="(" close=")">
|
||||
${item.fieldName} ${item.dataType}
|
||||
<if test="item.dataLength > 0">
|
||||
(${item.dataLength})
|
||||
</if>
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<!-- 查看超级表 -->
|
||||
<select id="showSuperTables" resultType="java.util.Map">
|
||||
SHOW ${dataBaseName}.STABLES LIKE '${superTableName}'
|
||||
</select>
|
||||
|
||||
<!-- 描述超级表结构 -->
|
||||
<select id="describeSuperTable" resultType="java.util.Map">
|
||||
DESCRIBE ${dataBaseName}.${superTableName}
|
||||
</select>
|
||||
|
||||
<!-- 为超级表添加列 -->
|
||||
<update id="addColumnForSuperTable">
|
||||
ALTER STABLE ${dataBaseName}.${superTableName} ADD COLUMN ${column.fieldName} ${column.dataType}
|
||||
<if test="column.dataLength > 0">
|
||||
(${column.dataLength})
|
||||
</if>
|
||||
</update>
|
||||
|
||||
<!-- 为超级表删除列 -->
|
||||
<update id="dropColumnForSuperTable">
|
||||
ALTER STABLE ${dataBaseName}.${superTableName} DROP COLUMN ${column.fieldName}
|
||||
</update>
|
||||
|
||||
<!-- 修改列宽 -->
|
||||
<update id="modifyColumnWidthForSuperTable">
|
||||
ALTER STABLE ${dataBaseName}.${superTableName} MODIFY COLUMN ${column.fieldName} ${column.dataType}
|
||||
<if test="column.dataLength > 0">
|
||||
(${column.dataLength})
|
||||
</if>
|
||||
</update>
|
||||
|
||||
<!-- 为超级表添加标签 -->
|
||||
<update id="addTagForSuperTable">
|
||||
ALTER STABLE ${dataBaseName}.${superTableName} ADD TAG ${tag.fieldName} ${tag.dataType}
|
||||
<if test="tag.dataLength > 0">
|
||||
(${tag.dataLength})
|
||||
</if>
|
||||
</update>
|
||||
|
||||
<!-- 为超级表删除标签 -->
|
||||
<update id="dropTagForSuperTable">
|
||||
ALTER STABLE ${dataBaseName}.${superTableName} DROP TAG ${tag.fieldName}
|
||||
</update>
|
||||
|
||||
<!-- 创建子表 -->
|
||||
<update id="createTable">
|
||||
CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}
|
||||
USING ${dataBaseName}.${superTableName}
|
||||
TAGS
|
||||
<foreach item="item" collection="tags" separator=","
|
||||
open="(" close=")">
|
||||
#{item.fieldValue}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<!-- 创建子表,带有 TAGS -->
|
||||
<update id="createTableWithTags">
|
||||
CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}
|
||||
USING ${dataBaseName}.${superTableName}
|
||||
<foreach item="item" collection="tags" separator="," open="(" close=")">
|
||||
#{item.fieldName}
|
||||
</foreach>
|
||||
TAGS
|
||||
<foreach item="item" collection="tags" separator=","
|
||||
open="(" close=")">
|
||||
#{item.fieldValue}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
</mapper>
|
|
@ -1,86 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper">
|
||||
|
||||
<!-- 插入数据 -->
|
||||
<insert id="insertData">
|
||||
INSERT INTO ${dataBaseName}.${tableName}
|
||||
<foreach item="item" collection="columns" separator=","
|
||||
open="(" close=")">
|
||||
${item.fieldName}
|
||||
</foreach>
|
||||
VALUES
|
||||
<foreach item="item" collection="columns" separator=","
|
||||
open="(" close=")">
|
||||
#{item.fieldValue}
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<!-- 根据时间戳查询数据 -->
|
||||
<select id="selectByTimestamp" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO"
|
||||
resultType="Map">
|
||||
SELECT * FROM ${dataBaseName}.${tableName}
|
||||
WHERE ${fieldName} BETWEEN #{startTime} AND #{endTime}
|
||||
</select>
|
||||
|
||||
<!-- 获取时间范围内的数据条数 -->
|
||||
<select id="selectCountByTimestamp" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO"
|
||||
resultType="java.util.Map">
|
||||
SELECT COUNT(0) AS count
|
||||
FROM ${dataBaseName}.${tableName}
|
||||
WHERE ${fieldName} BETWEEN #{startTime} AND #{endTime}
|
||||
</select>
|
||||
|
||||
<!-- 获取最新数据 -->
|
||||
<select id="selectOneLastData" resultType="java.util.Map">
|
||||
SELECT LAST(time), *
|
||||
FROM ${tableName}
|
||||
WHERE device_id = #{deviceId}
|
||||
</select>
|
||||
|
||||
<!-- 根据标签获取最新数据 -->
|
||||
<select id="selectLastDataListByTags" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO"
|
||||
resultType="java.util.Map">
|
||||
SELECT LAST(*)
|
||||
FROM ${dataBaseName}.${stableName}
|
||||
GROUP BY ${tagsName}
|
||||
</select>
|
||||
|
||||
<!-- 获取历史数据 -->
|
||||
<select id="selectHistoryDataList" resultType="java.util.Map"
|
||||
parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
|
||||
SELECT ${fieldName} AS data, time
|
||||
FROM ${dataBaseName}.${tableName}
|
||||
WHERE time BETWEEN #{startTime} AND #{endTime}
|
||||
AND ${fieldName} IS NOT NULL
|
||||
ORDER BY time DESC
|
||||
LIMIT #{params.rows} OFFSET #{params.page}
|
||||
</select>
|
||||
|
||||
<!-- 获取实时数据 -->
|
||||
<select id="selectRealtimeDataList" resultType="java.util.Map"
|
||||
parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
|
||||
SELECT ${fieldName}, time
|
||||
FROM ${dataBaseName}.${tableName}
|
||||
</select>
|
||||
|
||||
<!-- 获取聚合数据 -->
|
||||
<select id="selectAggregateDataList" resultType="java.util.Map"
|
||||
parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
|
||||
SELECT ${aggregate}(${fieldName})
|
||||
FROM ${dataBaseName}.${tableName}
|
||||
WHERE ts BETWEEN #{startTime} AND #{endTime} INTERVAL (${interval})
|
||||
LIMIT #{num}
|
||||
</select>
|
||||
|
||||
<!-- 获取历史数据条数 -->
|
||||
<select id="selectHistoryCount" resultType="java.lang.Long">
|
||||
SELECT COUNT(time)
|
||||
FROM ${dataBaseName}.${tableName}
|
||||
WHERE time BETWEEN #{startTime} AND #{endTime}
|
||||
AND ${fieldName} IS NOT NULL
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -1,35 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdThingModelMessageMapper">
|
||||
|
||||
<!-- 创建物模型消息日志超级表 -->
|
||||
<update id="createSuperTable">
|
||||
CREATE STABLE thing_model_message_${productKey}(
|
||||
ts TIMESTAMP,
|
||||
id NCHAR(64),
|
||||
sys NCHAR(2048),
|
||||
method NCHAR(255),
|
||||
params NCHAR(2048),
|
||||
device_name NCHAR(64)
|
||||
)TAGS (
|
||||
device_key NCHAR(50)
|
||||
)
|
||||
</update>
|
||||
|
||||
<!-- 创建物模型消息日志子表,带有deviceKey的TAG -->
|
||||
<update id="createTableWithTag">
|
||||
CREATE STABLE ${deviceKey}
|
||||
USING thing_model_message_${productKey}(
|
||||
ts,
|
||||
id ,
|
||||
sys ,
|
||||
method ,
|
||||
params ,
|
||||
device_name
|
||||
)TAGS(
|
||||
#{device_key}
|
||||
)
|
||||
</update>
|
||||
</mapper>
|
Loading…
Reference in New Issue