Commit 89fb71e8573d1f6552d70a699e3a8b1ec8612f02

Authored by 安浩浩
1 parent 9b30d5d3

【优化功能】 优化 tdengine 操作数据库相关代码

Showing 34 changed files with 348 additions and 885 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/IotConstants.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.enums;
  2 +
  3 +/**
  4 + * Iot 常量
  5 + *
  6 + * @author 芋道源码
  7 + */
  8 +public interface IotConstants {
  9 +
  10 + /**
  11 + * 获取设备表名
  12 + * <p>
  13 + * 格式为 device_{productKey}_{deviceName}
  14 + */
  15 + String DEVICE_TABLE_NAME_FORMAT = "device_%s_%s";
  16 +
  17 + /**
  18 + * 获取产品属性超级表名 - 网关子设备
  19 + * <p>
  20 + * 格式为 gateway_sub_{productKey}
  21 + */
  22 + String GATEWAY_SUB_STABLE_NAME_FORMAT = "gateway_sub_%s";
  23 +
  24 + /**
  25 + * 获取产品属性超级表名 - 网关
  26 + * <p>
  27 + * 格式为 gateway_{productKey}
  28 + */
  29 + String GATEWAY_STABLE_NAME_FORMAT = "gateway_%s";
  30 +
  31 + /**
  32 + * 获取产品属性超级表名 - 设备
  33 + * <p>
  34 + * 格式为 device_{productKey}
  35 + */
  36 + String DEVICE_STABLE_NAME_FORMAT = "device_%s";
  37 +
  38 +}
0 \ No newline at end of file 39 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java
@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.device; @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.device;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO; 6 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO;
7 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataRespVO; 7 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataRespVO;
8 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO; 8 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
9 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotTimeDataRespVO; 9 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotTimeDataRespVO;
@@ -31,19 +31,17 @@ public class IotDeviceDataController { @@ -31,19 +31,17 @@ public class IotDeviceDataController {
31 @Resource 31 @Resource
32 private IotDeviceDataService deviceDataService; 32 private IotDeviceDataService deviceDataService;
33 33
34 - // TODO @haohao:是不是叫 get-latest 就好了。因为 data 已经在 url 里了哈  
35 - @GetMapping("/latest-data") 34 + @GetMapping("/latest")
36 @Operation(summary = "获取设备属性最新数据") 35 @Operation(summary = "获取设备属性最新数据")
37 - public CommonResult<List<IotDeviceDataRespVO>> getDevicePropertiesLatestData(@Valid IotDeviceDataReqVO deviceDataReqVO) {  
38 - List<IotDeviceDataDO> list = deviceDataService.getDevicePropertiesLatestData(deviceDataReqVO); 36 + public CommonResult<List<IotDeviceDataRespVO>> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) {
  37 + List<IotDeviceDataDO> list = deviceDataService.getLatestDeviceProperties(deviceDataReqVO);
39 return success(BeanUtils.toBean(list, IotDeviceDataRespVO.class)); 38 return success(BeanUtils.toBean(list, IotDeviceDataRespVO.class));
40 } 39 }
41 40
42 - // TODO @haohao:是不是叫 /history-data => page  
43 - @GetMapping("/history-data") 41 + @GetMapping("/history")
44 @Operation(summary = "获取设备属性历史数据") 42 @Operation(summary = "获取设备属性历史数据")
45 - public CommonResult<PageResult<IotTimeDataRespVO>> getDevicePropertiesHistoryData(@Valid IotDeviceDataReqVO deviceDataReqVO) {  
46 - PageResult<Map<String, Object>> list = deviceDataService.getDevicePropertiesHistoryData(deviceDataReqVO); 43 + public CommonResult<PageResult<IotTimeDataRespVO>> getHistoryDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) {
  44 + PageResult<Map<String, Object>> list = deviceDataService.getHistoryDeviceProperties(deviceDataReqVO);
47 return success(BeanUtils.toBean(list, IotTimeDataRespVO.class)); 45 return success(BeanUtils.toBean(list, IotTimeDataRespVO.class));
48 } 46 }
49 47
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataReqVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataPageReqVO.java
@@ -10,10 +10,9 @@ import java.time.LocalDateTime; @@ -10,10 +10,9 @@ import java.time.LocalDateTime;
10 10
11 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 11 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
12 12
13 -// TODO @haohao:IotDeviceDataPageReqVO  
14 @Schema(description = "管理后台 - IoT 设备数据 Request VO") 13 @Schema(description = "管理后台 - IoT 设备数据 Request VO")
15 @Data 14 @Data
16 -public class IotDeviceDataReqVO extends PageParam { 15 +public class IotDeviceDataPageReqVO extends PageParam {
17 16
18 @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177") 17 @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
19 private Long deviceId; 18 private Long deviceId;
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataRespVO.java
1 package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData; 1 package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData;
2 2
3 -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;  
4 -import com.alibaba.excel.annotation.ExcelProperty;  
5 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
6 -import lombok.Builder;  
7 import lombok.Data; 4 import lombok.Data;
8 5
9 import java.time.LocalDateTime; 6 import java.time.LocalDateTime;
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDataDO.java
1 package cn.iocoder.yudao.module.iot.dal.dataobject.device; 1 package cn.iocoder.yudao.module.iot.dal.dataobject.device;
2 2
3 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; 3 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
4 -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;  
5 -import com.baomidou.mybatisplus.annotation.TableId;  
6 -import io.swagger.v3.oas.annotations.media.Schema; 4 +import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
7 import lombok.AllArgsConstructor; 5 import lombok.AllArgsConstructor;
8 import lombok.Builder; 6 import lombok.Builder;
9 import lombok.Data; 7 import lombok.Data;
10 import lombok.NoArgsConstructor; 8 import lombok.NoArgsConstructor;
11 9
12 -import java.math.BigDecimal;  
13 import java.time.LocalDateTime; 10 import java.time.LocalDateTime;
14 11
15 /** 12 /**
@@ -23,39 +20,52 @@ import java.time.LocalDateTime; @@ -23,39 +20,52 @@ import java.time.LocalDateTime;
23 @AllArgsConstructor 20 @AllArgsConstructor
24 public class IotDeviceDataDO { 21 public class IotDeviceDataDO {
25 22
26 - // TODO @haohao:每个字段的关联关系,可以 @ 下哈。  
27 /** 23 /**
28 * 设备编号 24 * 设备编号
  25 + * <p>
  26 + * 关联 {@link IotDeviceDO#getId()}
29 */ 27 */
30 private Long deviceId; 28 private Long deviceId;
31 29
32 /** 30 /**
33 * 物模型编号 31 * 物模型编号
  32 + * <p>
  33 + * 关联 {@link IotThinkModelFunctionDO#getId()}
34 */ 34 */
35 private Long thinkModelFunctionId; 35 private Long thinkModelFunctionId;
36 36
37 /** 37 /**
38 * 产品标识 38 * 产品标识
  39 + * <p>
  40 + * 关联 {@link IotProductDO#getProductKey()}
39 */ 41 */
40 private String productKey; 42 private String productKey;
41 43
42 /** 44 /**
43 * 设备名称 45 * 设备名称
  46 + * <p>
  47 + * 冗余 {@link IotDeviceDO#getDeviceName()}
44 */ 48 */
45 private String deviceName; 49 private String deviceName;
46 50
47 /** 51 /**
48 * 属性标识符 52 * 属性标识符
  53 + * <p>
  54 + * 关联 {@link IotThinkModelFunctionDO#getIdentifier()}
49 */ 55 */
50 private String identifier; 56 private String identifier;
51 57
52 /** 58 /**
53 * 属性名称 59 * 属性名称
  60 + * <p>
  61 + * 关联 {@link IotThinkModelFunctionDO#getName()}
54 */ 62 */
55 private String name; 63 private String name;
56 64
57 /** 65 /**
58 * 数据类型 66 * 数据类型
  67 + * <p>
  68 + * 关联 {@link IotThinkModelFunctionDO#getProperty()#getDataType()}
59 */ 69 */
60 private String dataType; 70 private String dataType;
61 71
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectDO.java
@@ -42,12 +42,6 @@ public class SelectDO { @@ -42,12 +42,6 @@ public class SelectDO {
42 */ 42 */
43 private String type; 43 private String type;
44 44
45 - // TODO @haohao:这个字段,是啥哈?  
46 - /**  
47 - * 查询条件  
48 - */  
49 - private Set<Integer> orgIds;  
50 -  
51 /** 45 /**
52 * 设备ID 46 * 设备ID
53 */ 47 */
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java
@@ -27,14 +27,17 @@ public class SelectVisualDO { @@ -27,14 +27,17 @@ public class SelectVisualDO {
27 * 查询类型,0历史数据,1实时数据,2聚合数据 27 * 查询类型,0历史数据,1实时数据,2聚合数据
28 */ 28 */
29 private int type; 29 private int type;
  30 +
30 /** 31 /**
31 * 查询的数据量 32 * 查询的数据量
32 */ 33 */
33 private int num; 34 private int num;
  35 +
34 /** 36 /**
35 * 聚合函数 37 * 聚合函数
36 */ 38 */
37 private String aggregate; 39 private String aggregate;
  40 +
38 /** 41 /**
39 * 统计间隔数字+s/m/h/d 42 * 统计间隔数字+s/m/h/d
40 * 比如1s,1m,1h,1d代表1秒,1分钟,1小时,1天 43 * 比如1s,1m,1h,1d代表1秒,1分钟,1小时,1天
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TableManager.java deleted
1 -package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;  
2 -  
3 -import java.util.List;  
4 -  
5 -// TODO @haohao:这个还有用哇?  
6 -/**  
7 - * TableManager 类用于管理 TDengine 表的创建、删除和结构信息获取  
8 - */  
9 -public class TableManager {  
10 -  
11 - /**  
12 - * 创建超级表模板(含存在判断)  
13 - */  
14 - private static final String CREATE_STABLE_INE_TPL = "CREATE STABLE IF NOT EXISTS %s (%s) TAGS (%s);";  
15 -  
16 - /**  
17 - * 删除超级表  
18 - */  
19 - private static final String DROP_STABLE_TPL = "DROP STABLE IF EXISTS %s;";  
20 -  
21 - /**  
22 - * 获取表的结构信息  
23 - */  
24 - private static final String DESC_TB_TPL = "DESCRIBE %s;";  
25 -  
26 - /**  
27 - * 超级表增加列  
28 - */  
29 - private static final String ALTER_STABLE_ADD_COL_TPL = "ALTER STABLE %s ADD COLUMN %s;";  
30 -  
31 - /**  
32 - * 超级表修改列  
33 - */  
34 - private static final String ALTER_STABLE_MODIFY_COL_TPL = "ALTER STABLE %s MODIFY COLUMN %s;";  
35 -  
36 - /**  
37 - * 超级表删除列  
38 - */  
39 - private static final String ALTER_STABLE_DROP_COL_TPL = "ALTER STABLE %s DROP COLUMN %s;";  
40 -  
41 - /**  
42 - * 创建普通表模板(含存在判断)  
43 - */  
44 - private static final String CREATE_CTABLE_INE_TPL = "CREATE TABLE IF NOT EXISTS %s (%s)";  
45 -  
46 - /**  
47 - * 获取创建表sql  
48 - */  
49 - public static String getCreateSTableSql(String tbName, List<TdFieldDO> fields, TdFieldDO... tags) {  
50 - if (fields.isEmpty()) {  
51 - return null;  
52 - }  
53 -  
54 - // 生成字段片段  
55 - StringBuilder sbField = new StringBuilder("time TIMESTAMP,");  
56 -  
57 - for (TdFieldDO field : fields) {  
58 - sbField.append(FieldParser.getFieldDefine(field));  
59 - sbField.append(",");  
60 - }  
61 - sbField.deleteCharAt(sbField.length() - 1);  
62 -  
63 - String fieldFrag = sbField.toString();  
64 -  
65 - // 生成tag  
66 - StringBuilder sbTag = new StringBuilder();  
67 - for (TdFieldDO tag : tags) {  
68 - sbTag.append(FieldParser.getFieldDefine(tag))  
69 - .append(",");  
70 - }  
71 - sbTag.deleteCharAt(sbTag.length() - 1);  
72 -  
73 - return String.format(CREATE_STABLE_INE_TPL, tbName, fieldFrag, sbTag);  
74 -  
75 - }  
76 -  
77 - /**  
78 - * 获取创建普通表sql  
79 - */  
80 - public static String getCreateCTableSql(String tbName, List<TdFieldDO> fields) {  
81 - if (fields.size() == 0) {  
82 - return null;  
83 - }  
84 -  
85 - //生成字段片段  
86 - StringBuilder sbField = new StringBuilder("time timestamp,");  
87 -  
88 - for (TdFieldDO field : fields) {  
89 - sbField.append(FieldParser.getFieldDefine(field));  
90 - sbField.append(",");  
91 - }  
92 - sbField.deleteCharAt(sbField.length() - 1);  
93 -  
94 - String fieldFrag = sbField.toString();  
95 -  
96 - return String.format(CREATE_CTABLE_INE_TPL, tbName, fieldFrag);  
97 -  
98 - }  
99 -  
100 -  
101 - /**  
102 - * 取正确的表名  
103 - *  
104 - * @param name 表象  
105 - */  
106 - public static String rightTbName(String name) {  
107 - return name.toLowerCase().replace("-" , "_");  
108 - }  
109 -  
110 - /**  
111 - * 获取表详情的sql  
112 - */  
113 - public static String getDescTableSql(String tbName) {  
114 - return String.format(DESC_TB_TPL, tbName);  
115 - }  
116 -  
117 - /**  
118 - * 获取添加字段sql  
119 - */  
120 - public static String getAddSTableColumnSql(String tbName, List<TdFieldDO> fields) {  
121 - StringBuilder sbAdd = new StringBuilder();  
122 - for (TdFieldDO field : fields) {  
123 - sbAdd.append(String.format(ALTER_STABLE_ADD_COL_TPL,  
124 - tbName,  
125 - FieldParser.getFieldDefine(field)  
126 - ));  
127 - }  
128 - return sbAdd.toString();  
129 - }  
130 -  
131 - /**  
132 - * 获取修改字段sql  
133 - */  
134 - public static String getModifySTableColumnSql(String tbName, List<TdFieldDO> fields) {  
135 - StringBuilder sbModify = new StringBuilder();  
136 - for (TdFieldDO field : fields) {  
137 - sbModify.append(String.format(ALTER_STABLE_MODIFY_COL_TPL,  
138 - tbName,  
139 - FieldParser.getFieldDefine(field)  
140 - ));  
141 - }  
142 - return sbModify.toString();  
143 - }  
144 -  
145 - /**  
146 - * 获取删除字段sql  
147 - */  
148 - public static String getDropSTableColumnSql(String tbName, List<TdFieldDO> fields) {  
149 - StringBuilder sbDrop = new StringBuilder();  
150 - for (TdFieldDO field : fields) {  
151 - sbDrop.append(String.format(ALTER_STABLE_DROP_COL_TPL,  
152 - tbName,  
153 - field.getFieldName()  
154 - ));  
155 - }  
156 - return sbDrop.toString();  
157 - }  
158 -  
159 -}  
160 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineSuperTableMapper.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDDLMapper.java
1 package cn.iocoder.yudao.module.iot.dal.tdengine; 1 package cn.iocoder.yudao.module.iot.dal.tdengine;
2 2
  3 +import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
3 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO; 4 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
4 import com.baomidou.dynamic.datasource.annotation.DS; 5 import com.baomidou.dynamic.datasource.annotation.DS;
5 import com.baomidou.mybatisplus.annotation.InterceptorIgnore; 6 import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
6 import org.apache.ibatis.annotations.Mapper; 7 import org.apache.ibatis.annotations.Mapper;
  8 +import org.apache.ibatis.annotations.Param;
7 9
8 import java.util.List; 10 import java.util.List;
9 import java.util.Map; 11 import java.util.Map;
10 12
11 /** 13 /**
12 - * TD 引擎的超级表 Mapper 14 + * 专门处理 DDL(数据定义语言)操作,包含所有的数据库和表的定义操作,例如创建数据库、创建超级表、创建子表等
13 */ 15 */
14 @Mapper 16 @Mapper
15 @DS("tdengine") 17 @DS("tdengine")
16 -public interface TdEngineSuperTableMapper { 18 +public interface TdEngineDDLMapper {
  19 +
  20 + /**
  21 + * 创建数据库
  22 + * SQL:CREATE DATABASE [IF NOT EXISTS] db_name [database_options];
  23 + *
  24 + * @param dataBaseName 数据库名称
  25 + */
  26 + @TenantIgnore
  27 + void createDatabase(@Param("dataBaseName") String dataBaseName);
17 28
18 /** 29 /**
19 * 创建超级表 30 * 创建超级表
@@ -25,7 +36,7 @@ public interface TdEngineSuperTableMapper { @@ -25,7 +36,7 @@ public interface TdEngineSuperTableMapper {
25 * columns 列信息 36 * columns 列信息
26 * tags 标签信息 37 * tags 标签信息
27 */ 38 */
28 - @InterceptorIgnore(tenantLine = "true") 39 + @TenantIgnore
29 void createSuperTable(TdTableDO superTable); 40 void createSuperTable(TdTableDO superTable);
30 41
31 /** 42 /**
@@ -36,7 +47,7 @@ public interface TdEngineSuperTableMapper { @@ -36,7 +47,7 @@ public interface TdEngineSuperTableMapper {
36 * dataBaseName 数据库名称 47 * dataBaseName 数据库名称
37 * superTableName 超级表名称 48 * superTableName 超级表名称
38 */ 49 */
39 - @InterceptorIgnore(tenantLine = "true") 50 + @TenantIgnore
40 List<Map<String, Object>> showSuperTables(TdTableDO superTable); 51 List<Map<String, Object>> showSuperTables(TdTableDO superTable);
41 52
42 /** 53 /**
@@ -47,7 +58,7 @@ public interface TdEngineSuperTableMapper { @@ -47,7 +58,7 @@ public interface TdEngineSuperTableMapper {
47 * dataBaseName 数据库名称 58 * dataBaseName 数据库名称
48 * superTableName 超级表名称 59 * superTableName 超级表名称
49 */ 60 */
50 - @InterceptorIgnore(tenantLine = "true") 61 + @TenantIgnore
51 List<Map<String, Object>> describeSuperTable(TdTableDO superTable); 62 List<Map<String, Object>> describeSuperTable(TdTableDO superTable);
52 63
53 /** 64 /**
@@ -59,7 +70,7 @@ public interface TdEngineSuperTableMapper { @@ -59,7 +70,7 @@ public interface TdEngineSuperTableMapper {
59 * superTableName 超级表名称 70 * superTableName 超级表名称
60 * column 列信息 71 * column 列信息
61 */ 72 */
62 - @InterceptorIgnore(tenantLine = "true") 73 + @TenantIgnore
63 void addColumnForSuperTable(TdTableDO superTable); 74 void addColumnForSuperTable(TdTableDO superTable);
64 75
65 /** 76 /**
@@ -71,7 +82,7 @@ public interface TdEngineSuperTableMapper { @@ -71,7 +82,7 @@ public interface TdEngineSuperTableMapper {
71 * superTableName 超级表名称 82 * superTableName 超级表名称
72 * column 列信息 83 * column 列信息
73 */ 84 */
74 - @InterceptorIgnore(tenantLine = "true") 85 + @TenantIgnore
75 void dropColumnForSuperTable(TdTableDO superTable); 86 void dropColumnForSuperTable(TdTableDO superTable);
76 87
77 /** 88 /**
@@ -83,7 +94,7 @@ public interface TdEngineSuperTableMapper { @@ -83,7 +94,7 @@ public interface TdEngineSuperTableMapper {
83 * superTableName 超级表名称 94 * superTableName 超级表名称
84 * column 列信息 95 * column 列信息
85 */ 96 */
86 - @InterceptorIgnore(tenantLine = "true") 97 + @TenantIgnore
87 void modifyColumnWidthForSuperTable(TdTableDO superTable); 98 void modifyColumnWidthForSuperTable(TdTableDO superTable);
88 99
89 100
@@ -95,7 +106,7 @@ public interface TdEngineSuperTableMapper { @@ -95,7 +106,7 @@ public interface TdEngineSuperTableMapper {
95 * superTableName 超级表名称 106 * superTableName 超级表名称
96 * tag 标签信息 107 * tag 标签信息
97 */ 108 */
98 - @InterceptorIgnore(tenantLine = "true") 109 + @TenantIgnore
99 void addTagForSuperTable(TdTableDO superTable); 110 void addTagForSuperTable(TdTableDO superTable);
100 111
101 /** 112 /**
@@ -106,6 +117,33 @@ public interface TdEngineSuperTableMapper { @@ -106,6 +117,33 @@ public interface TdEngineSuperTableMapper {
106 * superTableName 超级表名称 117 * superTableName 超级表名称
107 * tag 标签信息 118 * tag 标签信息
108 */ 119 */
109 - @InterceptorIgnore(tenantLine = "true") 120 + @TenantIgnore
110 void dropTagForSuperTable(TdTableDO superTable); 121 void dropTagForSuperTable(TdTableDO superTable);
111 -}  
112 \ No newline at end of file 122 \ No newline at end of file
  123 +
  124 + /**
  125 + * 创建子表 - 创建子表
  126 + * SQL:CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...);
  127 + *
  128 + * @param table 表信息
  129 + * dataBaseName 数据库名称
  130 + * superTableName 超级表名称
  131 + * tableName 子表名称
  132 + * tags TAG 字段
  133 + */
  134 + @TenantIgnore
  135 + void createTable(TdTableDO table);
  136 +
  137 + /**
  138 + * 创建子表 - 创建子表并指定标签的值
  139 + * SQL:CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...);
  140 + *
  141 + * @param table 表信息
  142 + * dataBaseName 数据库名称
  143 + * superTableName 超级表名称
  144 + * tableName 子表名称
  145 + * tags TAG 字段
  146 + */
  147 + @TenantIgnore
  148 + void createTableWithTags(TdTableDO table);
  149 +
  150 +}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineQueryMapper.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDMLMapper.java
1 package cn.iocoder.yudao.module.iot.dal.tdengine; 1 package cn.iocoder.yudao.module.iot.dal.tdengine;
2 2
  3 +import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
3 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO; 4 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO;
4 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO; 5 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
5 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO; 6 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO;
  7 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
6 import com.baomidou.dynamic.datasource.annotation.DS; 8 import com.baomidou.dynamic.datasource.annotation.DS;
7 -import com.baomidou.mybatisplus.annotation.InterceptorIgnore;  
8 import org.apache.ibatis.annotations.Mapper; 9 import org.apache.ibatis.annotations.Mapper;
9 10
10 import java.util.List; 11 import java.util.List;
11 import java.util.Map; 12 import java.util.Map;
12 13
13 /** 14 /**
14 - * TD 引擎的查询 Mapper 15 + * 专门处理 TD Engine 的 DML(数据操作语言)操作,处理所有的数据查询和写入操作,如插入数据、查询数据等
15 */ 16 */
16 @Mapper 17 @Mapper
17 @DS("tdengine") 18 @DS("tdengine")
18 -public interface TdEngineQueryMapper { 19 +public interface TdEngineDMLMapper {
  20 +
  21 + /**
  22 + * 插入数据 - 指定列插入数据
  23 + *
  24 + * @param table 数据
  25 + * dataBaseName 数据库名
  26 + * tableName 表名
  27 + * columns 列
  28 + */
  29 + @TenantIgnore
  30 + void insertData(TdTableDO table);
19 31
20 /** 32 /**
21 * 根据时间戳查询数据 33 * 根据时间戳查询数据
22 * 34 *
23 * @param selectDO 查询条件 35 * @param selectDO 查询条件
24 - * @return 查询结果 36 + * @return 查询结果列表
25 */ 37 */
  38 + @TenantIgnore
26 List<Map<String, Object>> selectByTimestamp(SelectDO selectDO); 39 List<Map<String, Object>> selectByTimestamp(SelectDO selectDO);
27 40
28 - // TODO @haohao:最好方法的命名,和数据库操作的保持一直。get => select。然后 selectList or selectOne  
29 /** 41 /**
30 * 根据时间戳获取数据条数 42 * 根据时间戳获取数据条数
31 * 43 *
32 * @param selectDO 查询条件 44 * @param selectDO 查询条件
33 * @return 数据条数 45 * @return 数据条数
34 */ 46 */
35 - Map<String, Long> getCountByTimestamp(SelectDO selectDO); 47 + @TenantIgnore
  48 + Map<String, Long> selectCountByTimestamp(SelectDO selectDO);
36 49
37 /** 50 /**
38 * 获取最新数据 51 * 获取最新数据
@@ -40,40 +53,44 @@ public interface TdEngineQueryMapper { @@ -40,40 +53,44 @@ public interface TdEngineQueryMapper {
40 * @param selectDO 查询条件 53 * @param selectDO 查询条件
41 * @return 最新数据 54 * @return 最新数据
42 */ 55 */
43 - Map<String, Object> getLastData(SelectDO selectDO); 56 + @TenantIgnore
  57 + Map<String, Object> selectOneLastData(SelectDO selectDO);
44 58
45 /** 59 /**
46 - * 获取历史数据 60 + * 获取历史数据列表
47 * 61 *
48 * @param selectVisualDO 查询条件 62 * @param selectVisualDO 查询条件
49 * @return 历史数据列表 63 * @return 历史数据列表
50 */ 64 */
51 - @InterceptorIgnore(tenantLine = "true")  
52 - List<Map<String, Object>> getHistoryData(SelectVisualDO selectVisualDO); 65 + @TenantIgnore
  66 + List<Map<String, Object>> selectHistoryDataList(SelectVisualDO selectVisualDO);
53 67
54 /** 68 /**
55 - * 获取实时数据 69 + * 获取实时数据列表
56 * 70 *
57 * @param selectVisualDO 查询条件 71 * @param selectVisualDO 查询条件
58 * @return 实时数据列表 72 * @return 实时数据列表
59 */ 73 */
60 - List<Map<String, Object>> getRealtimeData(SelectVisualDO selectVisualDO); 74 + @TenantIgnore
  75 + List<Map<String, Object>> selectRealtimeDataList(SelectVisualDO selectVisualDO);
61 76
62 /** 77 /**
63 - * 获取聚合数据 78 + * 获取聚合数据列表
64 * 79 *
65 * @param selectVisualDO 查询条件 80 * @param selectVisualDO 查询条件
66 * @return 聚合数据列表 81 * @return 聚合数据列表
67 */ 82 */
68 - List<Map<String, Object>> getAggregateData(SelectVisualDO selectVisualDO); 83 + @TenantIgnore
  84 + List<Map<String, Object>> selectAggregateDataList(SelectVisualDO selectVisualDO);
69 85
70 /** 86 /**
71 - * 根据标签获取最新数据 87 + * 根据标签获取最新数据列表
72 * 88 *
73 * @param tagsSelectDO 查询条件 89 * @param tagsSelectDO 查询条件
74 * @return 最新数据列表 90 * @return 最新数据列表
75 */ 91 */
76 - List<Map<String, Object>> getLastDataByTags(TagsSelectDO tagsSelectDO); 92 + @TenantIgnore
  93 + List<Map<String, Object>> selectLastDataListByTags(TagsSelectDO tagsSelectDO);
77 94
78 /** 95 /**
79 * 获取历史数据条数 96 * 获取历史数据条数
@@ -81,6 +98,6 @@ public interface TdEngineQueryMapper { @@ -81,6 +98,6 @@ public interface TdEngineQueryMapper {
81 * @param selectVisualDO 查询条件 98 * @param selectVisualDO 查询条件
82 * @return 数据条数 99 * @return 数据条数
83 */ 100 */
84 - @InterceptorIgnore(tenantLine = "true")  
85 - Long getHistoryCount(SelectVisualDO selectVisualDO);  
86 -} 101 + @TenantIgnore
  102 + Long selectHistoryCount(SelectVisualDO selectVisualDO);
  103 +}
87 \ No newline at end of file 104 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDataWriterMapper.java deleted
1 -package cn.iocoder.yudao.module.iot.dal.tdengine;  
2 -  
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;  
4 -import com.baomidou.dynamic.datasource.annotation.DS;  
5 -import com.baomidou.mybatisplus.annotation.InterceptorIgnore;  
6 -import org.apache.ibatis.annotations.Mapper;  
7 -  
8 -/**  
9 - * TD 引擎的数据写入 Mapper  
10 - */  
11 -@Mapper  
12 -@DS("tdengine")  
13 -public interface TdEngineDataWriterMapper {  
14 -  
15 - /**  
16 - * 插入数据 - 指定列插入数据  
17 - *  
18 - * @param table 数据  
19 - * dataBaseName 数据库名  
20 - * tableName 表名  
21 - * columns 列  
22 - */  
23 - @InterceptorIgnore(tenantLine = "true")  
24 - void insertData(TdTableDO table);  
25 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDatabaseMapper.java deleted
1 -package cn.iocoder.yudao.module.iot.dal.tdengine;  
2 -  
3 -import com.baomidou.dynamic.datasource.annotation.DS;  
4 -import com.baomidou.mybatisplus.annotation.InterceptorIgnore;  
5 -import org.apache.ibatis.annotations.Mapper;  
6 -import org.apache.ibatis.annotations.Param;  
7 -  
8 -// TODO @haohao:InterceptorIgnore 忽略租户,可以在每个方法上,添加 @TenantIgnore 哈。  
9 -/**  
10 - * TD 引擎的数据库 Mapper  
11 - */  
12 -@Mapper  
13 -@DS("tdengine")  
14 -public interface TdEngineDatabaseMapper {  
15 -  
16 - /**  
17 - * 创建数据库  
18 - * SQL:CREATE DATABASE [IF NOT EXISTS] db_name [database_options];  
19 - *  
20 - * @param dataBaseName 数据库名称  
21 - */  
22 - @InterceptorIgnore(tenantLine = "true")  
23 - void createDatabase(@Param("dataBaseName") String dataBaseName);  
24 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineTableMapper.java deleted
1 -package cn.iocoder.yudao.module.iot.dal.tdengine;  
2 -  
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;  
4 -import com.baomidou.dynamic.datasource.annotation.DS;  
5 -import com.baomidou.mybatisplus.annotation.InterceptorIgnore;  
6 -import org.apache.ibatis.annotations.Mapper;  
7 -  
8 -/**  
9 - * TD 引擎的表 Mapper  
10 - */  
11 -@Mapper  
12 -@DS("tdengine")  
13 -public interface TdEngineTableMapper {  
14 -  
15 - /**  
16 - * 创建子表 - 创建子表  
17 - * SQL:CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...);  
18 - *  
19 - * @param table 表信息  
20 - * dataBaseName 数据库名称  
21 - * superTableName 超级表名称  
22 - * tableName 子表名称  
23 - * tags TAG 字段  
24 - */  
25 - @InterceptorIgnore(tenantLine = "true")  
26 - void createTable(TdTableDO table);  
27 -  
28 - /**  
29 - * 创建子表 - 创建子表并指定标签的值  
30 - * SQL:CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...);  
31 - *  
32 - * @param table 表信息  
33 - * dataBaseName 数据库名称  
34 - * superTableName 超级表名称  
35 - * tableName 子表名称  
36 - * tags TAG 字段  
37 - */  
38 - @InterceptorIgnore(tenantLine = "true")  
39 - void createTableWithTags(TdTableDO table);  
40 -  
41 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataService.java
1 package cn.iocoder.yudao.module.iot.service.device; 1 package cn.iocoder.yudao.module.iot.service.device;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO; 4 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO;
5 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO; 5 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
6 import jakarta.validation.Valid; 6 import jakarta.validation.Valid;
7 7
@@ -31,7 +31,7 @@ public interface IotDeviceDataService { @@ -31,7 +31,7 @@ public interface IotDeviceDataService {
31 * @param deviceId 设备编号 31 * @param deviceId 设备编号
32 * @return 设备属性最新数据 32 * @return 设备属性最新数据
33 */ 33 */
34 - List<IotDeviceDataDO> getDevicePropertiesLatestData(@Valid IotDeviceDataReqVO deviceId); 34 + List<IotDeviceDataDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceId);
35 35
36 /** 36 /**
37 * 获得设备属性历史数据 37 * 获得设备属性历史数据
@@ -39,5 +39,5 @@ public interface IotDeviceDataService { @@ -39,5 +39,5 @@ public interface IotDeviceDataService {
39 * @param deviceDataReqVO 设备属性历史数据 Request VO 39 * @param deviceDataReqVO 设备属性历史数据 Request VO
40 * @return 设备属性历史数据 40 * @return 设备属性历史数据
41 */ 41 */
42 - PageResult<Map<String, Object>> getDevicePropertiesHistoryData(@Valid IotDeviceDataReqVO deviceDataReqVO); 42 + PageResult<Map<String, Object>> getHistoryDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO);
43 } 43 }
44 \ No newline at end of file 44 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataServiceImpl.java
1 package cn.iocoder.yudao.module.iot.service.device; 1 package cn.iocoder.yudao.module.iot.service.device;
2 2
3 import cn.hutool.core.date.DateUtil; 3 import cn.hutool.core.date.DateUtil;
  4 +import cn.hutool.core.util.StrUtil;
4 import cn.hutool.json.JSONObject; 5 import cn.hutool.json.JSONObject;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO; 7 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO;
7 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; 8 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
8 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO; 9 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
9 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO; 10 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
10 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; 11 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage;
11 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; 12 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
12 import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO; 13 import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
  14 +import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper;
  15 +import cn.iocoder.yudao.module.iot.enums.IotConstants;
13 import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum; 16 import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
14 import cn.iocoder.yudao.module.iot.service.tdengine.IotThingModelMessageService; 17 import cn.iocoder.yudao.module.iot.service.tdengine.IotThingModelMessageService;
15 -import cn.iocoder.yudao.module.iot.service.tdengine.TdEngineQueryService;  
16 import cn.iocoder.yudao.module.iot.service.thinkmodelfunction.IotThinkModelFunctionService; 18 import cn.iocoder.yudao.module.iot.service.thinkmodelfunction.IotThinkModelFunctionService;
17 import jakarta.annotation.Resource; 19 import jakarta.annotation.Resource;
18 import jakarta.validation.Valid; 20 import jakarta.validation.Valid;
@@ -40,7 +42,7 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService { @@ -40,7 +42,7 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
40 @Resource 42 @Resource
41 private IotThinkModelFunctionService thinkModelFunctionService; 43 private IotThinkModelFunctionService thinkModelFunctionService;
42 @Resource 44 @Resource
43 - private TdEngineQueryService tdEngineQueryService; 45 + private TdEngineDMLMapper tdEngineDMLMapper;
44 46
45 @Resource 47 @Resource
46 private DeviceDataRedisDAO deviceDataRedisDAO; 48 private DeviceDataRedisDAO deviceDataRedisDAO;
@@ -66,7 +68,7 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService { @@ -66,7 +68,7 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
66 } 68 }
67 69
68 @Override 70 @Override
69 - public List<IotDeviceDataDO> getDevicePropertiesLatestData(@Valid IotDeviceDataReqVO deviceDataReqVO) { 71 + public List<IotDeviceDataDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) {
70 List<IotDeviceDataDO> list = new ArrayList<>(); 72 List<IotDeviceDataDO> list = new ArrayList<>();
71 // 1. 获取设备信息 73 // 1. 获取设备信息
72 IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId()); 74 IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
@@ -106,7 +108,7 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService { @@ -106,7 +108,7 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
106 } 108 }
107 109
108 @Override 110 @Override
109 - public PageResult<Map<String, Object>> getDevicePropertiesHistoryData(IotDeviceDataReqVO deviceDataReqVO) { 111 + public PageResult<Map<String, Object>> getHistoryDeviceProperties(IotDeviceDataPageReqVO deviceDataReqVO) {
110 PageResult<Map<String, Object>> pageResult = new PageResult<>(); 112 PageResult<Map<String, Object>> pageResult = new PageResult<>();
111 // 1. 获取设备信息 113 // 1. 获取设备信息
112 IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId()); 114 IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
@@ -121,17 +123,17 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService { @@ -121,17 +123,17 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
121 params.put("rows", deviceDataReqVO.getPageSize()); 123 params.put("rows", deviceDataReqVO.getPageSize());
122 params.put("page", (deviceDataReqVO.getPageNo() - 1) * deviceDataReqVO.getPageSize()); 124 params.put("page", (deviceDataReqVO.getPageNo() - 1) * deviceDataReqVO.getPageSize());
123 selectVisualDO.setParams(params); 125 selectVisualDO.setParams(params);
124 - pageResult.setList(tdEngineQueryService.getHistoryData(selectVisualDO));  
125 - pageResult.setTotal(tdEngineQueryService.getHistoryCount(selectVisualDO)); 126 + pageResult.setList(tdEngineDMLMapper.selectHistoryDataList(selectVisualDO));
  127 + pageResult.setTotal(tdEngineDMLMapper.selectHistoryCount(selectVisualDO));
126 return pageResult; 128 return pageResult;
127 } 129 }
128 130
129 private String getDatabaseName() { 131 private String getDatabaseName() {
130 - return url.substring(url.lastIndexOf("/") + 1); 132 + return StrUtil.subAfter(url, "/", true);
131 } 133 }
132 134
133 private static String getDeviceTableName(String productKey, String deviceName) { 135 private static String getDeviceTableName(String productKey, String deviceName) {
134 - return String.format("device_%s_%s", productKey.toLowerCase(), deviceName.toLowerCase()); 136 + return String.format(IotConstants.DEVICE_TABLE_NAME_FORMAT, productKey, deviceName);
135 } 137 }
136 138
137 -} 139 -}
  140 +}
138 \ No newline at end of file 141 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java
@@ -19,7 +19,9 @@ import org.springframework.stereotype.Service; @@ -19,7 +19,9 @@ import org.springframework.stereotype.Service;
19 import org.springframework.transaction.annotation.Transactional; 19 import org.springframework.transaction.annotation.Transactional;
20 import org.springframework.validation.annotation.Validated; 20 import org.springframework.validation.annotation.Validated;
21 21
  22 +import java.security.SecureRandom;
22 import java.time.LocalDateTime; 23 import java.time.LocalDateTime;
  24 +import java.util.Base64;
23 import java.util.Objects; 25 import java.util.Objects;
24 import java.util.UUID; 26 import java.util.UUID;
25 27
@@ -137,10 +139,13 @@ public class IotDeviceServiceImpl implements IotDeviceService { @@ -137,10 +139,13 @@ public class IotDeviceServiceImpl implements IotDeviceService {
137 * @return 生成的 MQTT Password 139 * @return 生成的 MQTT Password
138 */ 140 */
139 private String generateMqttPassword() { 141 private String generateMqttPassword() {
140 - // TODO @haohao:【后续优化】在实际应用中,建议使用更安全的方法生成 MQTT Password,如加密或哈希  
141 - return UUID.randomUUID().toString(); 142 + SecureRandom secureRandom = new SecureRandom();
  143 + byte[] passwordBytes = new byte[32]; // 256 位的随机数
  144 + secureRandom.nextBytes(passwordBytes);
  145 + return Base64.getUrlEncoder().withoutPadding().encodeToString(passwordBytes);
142 } 146 }
143 147
  148 +
144 /** 149 /**
145 * 生成唯一的 DeviceName 150 * 生成唯一的 DeviceName
146 * 151 *
@@ -214,30 +219,28 @@ public class IotDeviceServiceImpl implements IotDeviceService { @@ -214,30 +219,28 @@ public class IotDeviceServiceImpl implements IotDeviceService {
214 @Override 219 @Override
215 public void updateDeviceStatus(IotDeviceStatusUpdateReqVO updateReqVO) { 220 public void updateDeviceStatus(IotDeviceStatusUpdateReqVO updateReqVO) {
216 // 1. 校验存在 221 // 1. 校验存在
217 - // TODO @haohao:这里的 iotDeviceDO => device。一个是去掉 iot,一个是去掉 DO 后缀。这样,简洁一点。  
218 - IotDeviceDO iotDeviceDO = validateDeviceExists(updateReqVO.getId()); 222 + IotDeviceDO device = validateDeviceExists(updateReqVO.getId());
219 223
220 // 2.1 更新状态和更新时间 224 // 2.1 更新状态和更新时间
221 - IotDeviceDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceDO.class);  
222 - // TODO @haohao:下面几个状态的处理,可以考虑 if else if。这样,看起来会有层次感哈  
223 - // 2.2.1 以前是未激活,现在是上线,设置设备激活时间  
224 - // TODO @haohao:这里可以使用 ObjectUtils.equalsAny 类似这种哈。  
225 - if (Objects.equals(iotDeviceDO.getStatus(), IotDeviceStatusEnum.INACTIVE.getStatus())  
226 - && Objects.equals(updateObj.getStatus(), IotDeviceStatusEnum.ONLINE.getStatus())) {  
227 - updateObj.setActiveTime(LocalDateTime.now());  
228 - }  
229 - // 2.2.2 如果是上线,设置上线时间  
230 - if (Objects.equals(updateObj.getStatus(), IotDeviceStatusEnum.ONLINE.getStatus())) {  
231 - updateObj.setLastOnlineTime(LocalDateTime.now());  
232 - }  
233 - // 2.2.3 如果是离线,设置离线时间  
234 - if (Objects.equals(updateObj.getStatus(), IotDeviceStatusEnum.OFFLINE.getStatus())) {  
235 - updateObj.setLastOfflineTime(LocalDateTime.now()); 225 + IotDeviceDO updateDevice = BeanUtils.toBean(updateReqVO, IotDeviceDO.class);
  226 + // 2.2 更新状态相关时间
  227 + if (Objects.equals(device.getStatus(), IotDeviceStatusEnum.INACTIVE.getStatus())
  228 + && Objects.equals(updateDevice.getStatus(), IotDeviceStatusEnum.ONLINE.getStatus())) {
  229 + // 从未激活到在线,设置激活时间和最后上线时间
  230 + updateDevice.setActiveTime(LocalDateTime.now());
  231 + updateDevice.setLastOnlineTime(LocalDateTime.now());
  232 + } else if (Objects.equals(updateDevice.getStatus(), IotDeviceStatusEnum.ONLINE.getStatus())) {
  233 + // 如果是上线,设置最后上线时间
  234 + updateDevice.setLastOnlineTime(LocalDateTime.now());
  235 + } else if (Objects.equals(updateDevice.getStatus(), IotDeviceStatusEnum.OFFLINE.getStatus())) {
  236 + // 如果是离线,设置最后离线时间
  237 + updateDevice.setLastOfflineTime(LocalDateTime.now());
236 } 238 }
  239 +
237 // 2.3 设置状态更新时间 240 // 2.3 设置状态更新时间
238 - updateObj.setStatusLastUpdateTime(LocalDateTime.now()); 241 + updateDevice.setStatusLastUpdateTime(LocalDateTime.now());
239 // 2.4 更新到数据库 242 // 2.4 更新到数据库
240 - deviceMapper.updateById(updateObj); 243 + deviceMapper.updateById(updateDevice);
241 } 244 }
242 245
243 @Override 246 @Override
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotSuperTableService.java
@@ -15,4 +15,4 @@ public interface IotSuperTableService { @@ -15,4 +15,4 @@ public interface IotSuperTableService {
15 * 创建超级表数据模型 15 * 创建超级表数据模型
16 */ 16 */
17 void createSuperTableDataModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList); 17 void createSuperTableDataModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList);
18 -} 18 -}
  19 +}
19 \ No newline at end of file 20 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotSuperTableServiceImpl.java
@@ -9,6 +9,8 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser; @@ -9,6 +9,8 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser;
9 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO; 9 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
10 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO; 10 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
11 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; 11 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
  12 +import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDDLMapper;
  13 +import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper;
12 import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum; 14 import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
13 import jakarta.annotation.Resource; 15 import jakarta.annotation.Resource;
14 import lombok.extern.slf4j.Slf4j; 16 import lombok.extern.slf4j.Slf4j;
@@ -26,7 +28,7 @@ import java.util.stream.Collectors; @@ -26,7 +28,7 @@ import java.util.stream.Collectors;
26 public class IotSuperTableServiceImpl implements IotSuperTableService { 28 public class IotSuperTableServiceImpl implements IotSuperTableService {
27 29
28 @Resource 30 @Resource
29 - private TdEngineSuperTableService tdEngineSuperTableService; 31 + private TdEngineDDLMapper tdEngineDDLMapper;
30 32
31 @Value("${spring.datasource.dynamic.datasource.tdengine.url}") 33 @Value("${spring.datasource.dynamic.datasource.tdengine.url}")
32 private String url; 34 private String url;
@@ -42,9 +44,10 @@ public class IotSuperTableServiceImpl implements IotSuperTableService { @@ -42,9 +44,10 @@ public class IotSuperTableServiceImpl implements IotSuperTableService {
42 44
43 String superTableName = getSuperTableName(product.getDeviceType(), product.getProductKey()); 45 String superTableName = getSuperTableName(product.getDeviceType(), product.getProductKey());
44 String databaseName = getDatabaseName(); 46 String databaseName = getDatabaseName();
45 - Integer tableExists = tdEngineSuperTableService.checkSuperTableExists(new TdTableDO(databaseName, superTableName));  
46 47
47 - if (tableExists != null && tableExists > 0) { 48 + List<Map<String, Object>> results = tdEngineDDLMapper.showSuperTables(new TdTableDO(databaseName, superTableName));
  49 + int tableExists = results == null || results.isEmpty() ? 0 : results.size();
  50 + if (tableExists > 0) {
48 updateSuperTable(thingModel, product.getDeviceType()); 51 updateSuperTable(thingModel, product.getDeviceType());
49 } else { 52 } else {
50 createSuperTable(thingModel, product.getDeviceType()); 53 createSuperTable(thingModel, product.getDeviceType());
@@ -76,7 +79,7 @@ public class IotSuperTableServiceImpl implements IotSuperTableService { @@ -76,7 +79,7 @@ public class IotSuperTableServiceImpl implements IotSuperTableService {
76 String databaseName = getDatabaseName(); 79 String databaseName = getDatabaseName();
77 80
78 // 创建超级表 81 // 创建超级表
79 - tdEngineSuperTableService.createSuperTable(new TdTableDO(databaseName, superTableName, schemaFields, tagsFields)); 82 + tdEngineDDLMapper.createSuperTable(new TdTableDO(databaseName, superTableName, schemaFields, tagsFields));
80 } 83 }
81 84
82 /** 85 /**
@@ -98,7 +101,7 @@ public class IotSuperTableServiceImpl implements IotSuperTableService { @@ -98,7 +101,7 @@ public class IotSuperTableServiceImpl implements IotSuperTableService {
98 * 获取表的字段信息 101 * 获取表的字段信息
99 */ 102 */
100 private List<TdFieldDO> getTableFields(String tableName) { 103 private List<TdFieldDO> getTableFields(String tableName) {
101 - List<Map<String, Object>> tableDescription = tdEngineSuperTableService.describeSuperTable(new TdTableDO(getDatabaseName(), tableName)); 104 + List<Map<String, Object>> tableDescription = tdEngineDDLMapper.describeSuperTable(new TdTableDO(getDatabaseName(), tableName));
102 if (CollUtil.isEmpty(tableDescription)) { 105 if (CollUtil.isEmpty(tableDescription)) {
103 return Collections.emptyList(); 106 return Collections.emptyList();
104 } 107 }
@@ -127,32 +130,38 @@ public class IotSuperTableServiceImpl implements IotSuperTableService { @@ -127,32 +130,38 @@ public class IotSuperTableServiceImpl implements IotSuperTableService {
127 130
128 // 添加新增字段 131 // 添加新增字段
129 if (CollUtil.isNotEmpty(addFields)) { 132 if (CollUtil.isNotEmpty(addFields)) {
130 - tdEngineSuperTableService.addColumnsForSuperTable(TdTableDO.builder()  
131 - .dataBaseName(databaseName)  
132 - .superTableName(tableName)  
133 - .columns(addFields)  
134 - .build()); 133 + for (TdFieldDO addField : addFields) {
  134 + tdEngineDDLMapper.addColumnForSuperTable(TdTableDO.builder()
  135 + .dataBaseName(databaseName)
  136 + .superTableName(tableName)
  137 + .column(addField)
  138 + .build());
  139 + }
135 } 140 }
136 // 删除旧字段 141 // 删除旧字段
137 if (CollUtil.isNotEmpty(dropFields)) { 142 if (CollUtil.isNotEmpty(dropFields)) {
138 - tdEngineSuperTableService.dropColumnsForSuperTable(TdTableDO.builder()  
139 - .dataBaseName(databaseName)  
140 - .superTableName(tableName)  
141 - .columns(dropFields)  
142 - .build()); 143 + for (TdFieldDO dropField : dropFields) {
  144 + tdEngineDDLMapper.dropColumnForSuperTable(TdTableDO.builder()
  145 + .dataBaseName(databaseName)
  146 + .superTableName(tableName)
  147 + .column(dropField)
  148 + .build());
  149 + }
143 } 150 }
144 // 修改字段(先删除再添加) 151 // 修改字段(先删除再添加)
145 if (CollUtil.isNotEmpty(modifyFields)) { 152 if (CollUtil.isNotEmpty(modifyFields)) {
146 - tdEngineSuperTableService.dropColumnsForSuperTable(TdTableDO.builder()  
147 - .dataBaseName(databaseName)  
148 - .superTableName(tableName)  
149 - .columns(modifyFields)  
150 - .build());  
151 - tdEngineSuperTableService.addColumnsForSuperTable(TdTableDO.builder()  
152 - .dataBaseName(databaseName)  
153 - .superTableName(tableName)  
154 - .columns(addFields)  
155 - .build()); 153 + for (TdFieldDO modifyField : modifyFields) {
  154 + tdEngineDDLMapper.dropColumnForSuperTable(TdTableDO.builder()
  155 + .dataBaseName(databaseName)
  156 + .superTableName(tableName)
  157 + .column(modifyField)
  158 + .build());
  159 + tdEngineDDLMapper.addColumnForSuperTable(TdTableDO.builder()
  160 + .dataBaseName(databaseName)
  161 + .superTableName(tableName)
  162 + .column(modifyField)
  163 + .build());
  164 + }
156 } 165 }
157 } 166 }
158 167
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java
1 package cn.iocoder.yudao.module.iot.service.tdengine; 1 package cn.iocoder.yudao.module.iot.service.tdengine;
2 2
3 import cn.hutool.core.date.DateUtil; 3 import cn.hutool.core.date.DateUtil;
  4 +import cn.hutool.core.util.StrUtil;
  5 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; 6 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
5 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO; 7 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO;
6 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; 8 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
@@ -11,6 +13,9 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO; @@ -11,6 +13,9 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
11 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; 13 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage;
12 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; 14 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
13 import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO; 15 import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
  16 +import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDDLMapper;
  17 +import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper;
  18 +import cn.iocoder.yudao.module.iot.enums.IotConstants;
14 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; 19 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
15 import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum; 20 import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
16 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; 21 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
@@ -30,6 +35,14 @@ import java.util.stream.Collectors; @@ -30,6 +35,14 @@ import java.util.stream.Collectors;
30 @Service 35 @Service
31 public class IotThingModelMessageServiceImpl implements IotThingModelMessageService { 36 public class IotThingModelMessageServiceImpl implements IotThingModelMessageService {
32 37
  38 + private static final String TAG_NOTE = "TAG";
  39 + private static final String NOTE = "note";
  40 + private static final String TIME = "time";
  41 + private static final String DEVICE_KEY = "device_key";
  42 + private static final String DEVICE_NAME = "device_name";
  43 + private static final String PRODUCT_KEY = "product_key";
  44 + private static final String DEVICE_TYPE = "device_type";
  45 +
33 @Value("${spring.datasource.dynamic.datasource.tdengine.url}") 46 @Value("${spring.datasource.dynamic.datasource.tdengine.url}")
34 private String url; 47 private String url;
35 48
@@ -38,11 +51,9 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ @@ -38,11 +51,9 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
38 @Resource 51 @Resource
39 private IotDeviceService iotDeviceService; 52 private IotDeviceService iotDeviceService;
40 @Resource 53 @Resource
41 - private TdEngineTableService tdEngineTableService;  
42 - @Resource  
43 - private TdEngineSuperTableService tdEngineSuperTableService; 54 + private TdEngineDDLMapper tdEngineDDLMapper;
44 @Resource 55 @Resource
45 - private TdEngineDataWriterService tdEngineDataWriterService; 56 + private TdEngineDMLMapper tdEngineDMLMapper;
46 57
47 @Resource 58 @Resource
48 private DeviceDataRedisDAO deviceDataRedisDAO; 59 private DeviceDataRedisDAO deviceDataRedisDAO;
@@ -51,62 +62,64 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ @@ -51,62 +62,64 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
51 @Override 62 @Override
52 @TenantIgnore 63 @TenantIgnore
53 public void saveThingModelMessage(IotDeviceDO device, ThingModelMessage thingModelMessage) { 64 public void saveThingModelMessage(IotDeviceDO device, ThingModelMessage thingModelMessage) {
54 - // 判断设备状态,如果为未激活状态,创建数据表 65 + // 1. 判断设备状态,如果为未激活状态,创建数据表并更新设备状态
55 if (IotDeviceStatusEnum.INACTIVE.getStatus().equals(device.getStatus())) { 66 if (IotDeviceStatusEnum.INACTIVE.getStatus().equals(device.getStatus())) {
56 - // 创建设备数据表  
57 createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey()); 67 createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey());
58 - // 更新设备状态  
59 - // TODO @haohao:下面可以考虑,链式调用。iotDeviceService.updateDeviceStatus(new IotDeviceStatusUpdateReqVO().setid().setstatus())  
60 - IotDeviceStatusUpdateReqVO updateReqVO = new IotDeviceStatusUpdateReqVO();  
61 - updateReqVO.setId(device.getId());  
62 - updateReqVO.setStatus(IotDeviceStatusEnum.ONLINE.getStatus());  
63 - iotDeviceService.updateDeviceStatus(updateReqVO); 68 + iotDeviceService.updateDeviceStatus(new IotDeviceStatusUpdateReqVO()
  69 + .setId(device.getId())
  70 + .setStatus(IotDeviceStatusEnum.ONLINE.getStatus()));
64 } 71 }
65 72
66 - // TODO @haohao:这个变量,可以和 “过滤并收集有效的属性字段” 那块,因为关联度高一点。  
67 - // 获取设备属性 73 + // 2. 获取设备属性并进行物模型校验,过滤非物模型属性
68 Map<String, Object> params = thingModelMessage.dataToMap(); 74 Map<String, Object> params = thingModelMessage.dataToMap();
  75 + List<IotThinkModelFunctionDO> functionList = getValidFunctionList(thingModelMessage.getProductKey());
  76 + if (functionList.isEmpty()) {
  77 + return;
  78 + }
  79 +
  80 +
  81 + // 3. 过滤并收集有效的属性字段,缓存设备属性
  82 + List<TdFieldDO> schemaFieldValues = filterAndCollectValidFields(params, functionList, device, thingModelMessage.getTime());
  83 + if (schemaFieldValues.size() == 1) { // 仅有时间字段,无需保存
  84 + return;
  85 + }
  86 +
  87 + // 4. 构建并保存设备属性数据
  88 + tdEngineDMLMapper.insertData(TdTableDO.builder()
  89 + .dataBaseName(getDatabaseName())
  90 + .tableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()))
  91 + .columns(schemaFieldValues)
  92 + .build());
  93 + }
69 94
70 - // 物模型校验,过滤非物模型属性  
71 - List<IotThinkModelFunctionDO> functionList = iotThinkModelFunctionService  
72 - .getThinkModelFunctionListByProductKey(thingModelMessage.getProductKey()) 95 + private List<IotThinkModelFunctionDO> getValidFunctionList(String productKey) {
  96 + return iotThinkModelFunctionService
  97 + .getThinkModelFunctionListByProductKey(productKey)
73 .stream() 98 .stream()
74 .filter(function -> IotProductFunctionTypeEnum.PROPERTY.getType().equals(function.getType())) 99 .filter(function -> IotProductFunctionTypeEnum.PROPERTY.getType().equals(function.getType()))
75 .toList(); 100 .toList();
76 - if (functionList.isEmpty()) {  
77 - return;  
78 - } 101 + }
79 102
80 - // 获取属性标识符集合  
81 - // TODO @haohao:这个变量,可以和 “过滤并收集有效的属性字段” 那块,因为关联度高一点。另外,可以使用 CollectionUtils。convertSet  
82 - Set<String> propertyIdentifiers = functionList.stream()  
83 - .map(IotThinkModelFunctionDO::getIdentifier)  
84 - .collect(Collectors.toSet()); 103 + private List<TdFieldDO> filterAndCollectValidFields(Map<String, Object> params, List<IotThinkModelFunctionDO> functionList, IotDeviceDO device, Long time) {
  104 + // 1. 获取属性标识符集合
  105 + Set<String> propertyIdentifiers = CollectionUtils.convertSet(functionList, IotThinkModelFunctionDO::getIdentifier);
85 106
  107 + // 2. 构建属性标识符和属性的映射
86 Map<String, IotThinkModelFunctionDO> functionMap = functionList.stream() 108 Map<String, IotThinkModelFunctionDO> functionMap = functionList.stream()
87 .collect(Collectors.toMap(IotThinkModelFunctionDO::getIdentifier, function -> function)); 109 .collect(Collectors.toMap(IotThinkModelFunctionDO::getIdentifier, function -> function));
88 110
89 - // 过滤并收集有效的属性字段 111 + // 3. 过滤并收集有效的属性字段
90 List<TdFieldDO> schemaFieldValues = new ArrayList<>(); 112 List<TdFieldDO> schemaFieldValues = new ArrayList<>();
91 - schemaFieldValues.add(new TdFieldDO("time", thingModelMessage.getTime())); 113 + schemaFieldValues.add(new TdFieldDO(TIME, time));
92 params.forEach((key, val) -> { 114 params.forEach((key, val) -> {
93 if (propertyIdentifiers.contains(key)) { 115 if (propertyIdentifiers.contains(key)) {
94 schemaFieldValues.add(new TdFieldDO(key.toLowerCase(), val)); 116 schemaFieldValues.add(new TdFieldDO(key.toLowerCase(), val));
95 // 缓存设备属性 117 // 缓存设备属性
96 // TODO @haohao:这个缓存的写入,可以使用的时候 cache 么?被动读 118 // TODO @haohao:这个缓存的写入,可以使用的时候 cache 么?被动读
97 - setDeviceDataCache(device, functionMap.get(key), val, thingModelMessage.getTime()); 119 + setDeviceDataCache(device, functionMap.get(key), val, time);
98 } 120 }
99 }); 121 });
100 - // TODO @haohao:疑问,为什么 1 不继续哈?  
101 - if (schemaFieldValues.size() == 1) {  
102 - return;  
103 - }  
104 -  
105 - // 构建并保存设备属性数据  
106 - tdEngineDataWriterService.insertData(TdTableDO.builder().build()  
107 - .setDataBaseName(getDatabaseName())  
108 - .setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()))  
109 - .setColumns(schemaFieldValues)); 122 + return schemaFieldValues;
110 } 123 }
111 124
112 /** 125 /**
@@ -132,7 +145,6 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ @@ -132,7 +145,6 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
132 deviceDataRedisDAO.set(deviceData); 145 deviceDataRedisDAO.set(deviceData);
133 } 146 }
134 147
135 - // TODO @haohao:实现没问题哈。这个方法的空行有点多,逻辑分块上没这么明显。看看能不能改下。  
136 /** 148 /**
137 * 创建设备数据表 149 * 创建设备数据表
138 * 150 *
@@ -142,36 +154,37 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ @@ -142,36 +154,37 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
142 * @param deviceKey 设备 Key 154 * @param deviceKey 设备 Key
143 */ 155 */
144 private void createDeviceTable(Integer deviceType, String productKey, String deviceName, String deviceKey) { 156 private void createDeviceTable(Integer deviceType, String productKey, String deviceName, String deviceKey) {
  157 + // 1. 获取超级表名和数据库名
145 String superTableName = getProductPropertySTableName(deviceType, productKey); 158 String superTableName = getProductPropertySTableName(deviceType, productKey);
146 String dataBaseName = getDatabaseName(); 159 String dataBaseName = getDatabaseName();
147 160
148 - List<Map<String, Object>> maps = tdEngineSuperTableService.describeSuperTable(new TdTableDO(dataBaseName, superTableName)); 161 + // 2. 获取超级表的结构信息
  162 + List<Map<String, Object>> maps = tdEngineDDLMapper.describeSuperTable(new TdTableDO(dataBaseName, superTableName));
149 List<TdFieldDO> tagsFieldValues = new ArrayList<>(); 163 List<TdFieldDO> tagsFieldValues = new ArrayList<>();
150 -  
151 if (maps != null) { 164 if (maps != null) {
152 - // TODO @haohao:一些字符串,是不是可以枚举起来哈。  
153 - // TODO @haohao:这种过滤的,常用的,可以考虑用 CollectionUtils.filterList。一些常用的 stream 操作,适合封装哈  
154 - List<Map<String, Object>> taggedNotesList = maps.stream()  
155 - .filter(map -> "TAG".equals(map.get("note")))  
156 - .toList(); 165 + // 2.1 过滤出 TAG 类型的字段
  166 + List<Map<String, Object>> taggedNotesList = CollectionUtils.filterList(maps, map -> TAG_NOTE.equals(map.get(NOTE)));
  167 +
157 168
  169 + // 2.2 解析字段信息
158 tagsFieldValues = FieldParser.parse(taggedNotesList.stream() 170 tagsFieldValues = FieldParser.parse(taggedNotesList.stream()
159 .map(map -> List.of(map.get("field"), map.get("type"), map.get("length"))) 171 .map(map -> List.of(map.get("field"), map.get("type"), map.get("length")))
160 .collect(Collectors.toList())); 172 .collect(Collectors.toList()));
161 173
  174 + // 2.3 设置 TAG 字段的值
162 for (TdFieldDO tagsFieldValue : tagsFieldValues) { 175 for (TdFieldDO tagsFieldValue : tagsFieldValues) {
163 switch (tagsFieldValue.getFieldName()) { 176 switch (tagsFieldValue.getFieldName()) {
164 - case "product_key" -> tagsFieldValue.setFieldValue(productKey);  
165 - case "device_key" -> tagsFieldValue.setFieldValue(deviceKey);  
166 - case "device_name" -> tagsFieldValue.setFieldValue(deviceName);  
167 - case "device_type" -> tagsFieldValue.setFieldValue(deviceType); 177 + case PRODUCT_KEY -> tagsFieldValue.setFieldValue(productKey);
  178 + case DEVICE_KEY -> tagsFieldValue.setFieldValue(deviceKey);
  179 + case DEVICE_NAME -> tagsFieldValue.setFieldValue(deviceName);
  180 + case DEVICE_TYPE -> tagsFieldValue.setFieldValue(deviceType);
168 } 181 }
169 } 182 }
170 } 183 }
171 184
172 - // 创建设备数据表 185 + // 3. 创建设备数据表
173 String tableName = getDeviceTableName(productKey, deviceName); 186 String tableName = getDeviceTableName(productKey, deviceName);
174 - tdEngineTableService.createTable(TdTableDO.builder().build() 187 + tdEngineDDLMapper.createTable(TdTableDO.builder().build()
175 .setDataBaseName(dataBaseName) 188 .setDataBaseName(dataBaseName)
176 .setSuperTableName(superTableName) 189 .setSuperTableName(superTableName)
177 .setTableName(tableName) 190 .setTableName(tableName)
@@ -184,8 +197,7 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ @@ -184,8 +197,7 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
184 * @return 数据库名称 197 * @return 数据库名称
185 */ 198 */
186 private String getDatabaseName() { 199 private String getDatabaseName() {
187 - // TODO @haohao:可以使用 StrUtil.subAftetLast 这种方法  
188 - return url.substring(url.lastIndexOf("/") + 1); 200 + return StrUtil.subAfter(url, "/", true);
189 } 201 }
190 202
191 /** 203 /**
@@ -198,9 +210,9 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ @@ -198,9 +210,9 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
198 private static String getProductPropertySTableName(Integer deviceType, String productKey) { 210 private static String getProductPropertySTableName(Integer deviceType, String productKey) {
199 // TODO @haohao:枚举下,会好点哈。 211 // TODO @haohao:枚举下,会好点哈。
200 return switch (deviceType) { 212 return switch (deviceType) {
201 - case 1 -> String.format("gateway_sub_%s", productKey).toLowerCase();  
202 - case 2 -> String.format("gateway_%s", productKey).toLowerCase();  
203 - default -> String.format("device_%s", productKey).toLowerCase(); 213 + case 1 -> String.format(IotConstants.GATEWAY_SUB_STABLE_NAME_FORMAT, productKey).toLowerCase();
  214 + case 2 -> String.format(IotConstants.GATEWAY_STABLE_NAME_FORMAT, productKey).toLowerCase();
  215 + default -> String.format(IotConstants.DEVICE_STABLE_NAME_FORMAT, productKey).toLowerCase();
204 }; 216 };
205 } 217 }
206 218
@@ -212,7 +224,7 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ @@ -212,7 +224,7 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
212 * @return 设备表名 224 * @return 设备表名
213 */ 225 */
214 private static String getDeviceTableName(String productKey, String deviceName) { 226 private static String getDeviceTableName(String productKey, String deviceName) {
215 - return String.format("device_%s_%s", productKey.toLowerCase(), deviceName.toLowerCase()); 227 + return String.format(IotConstants.DEVICE_TABLE_NAME_FORMAT, productKey.toLowerCase(), deviceName.toLowerCase());
216 } 228 }
217 229
218 } 230 }
219 \ No newline at end of file 231 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDataWriterService.java deleted
1 -package cn.iocoder.yudao.module.iot.service.tdengine;  
2 -  
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;  
4 -  
5 -/**  
6 - * TD 引擎的数据写入 Service 接口  
7 - */  
8 -public interface TdEngineDataWriterService {  
9 -  
10 - /**  
11 - * 插入数据 - 指定列插入数据  
12 - *  
13 - * @param table 数据  
14 - * dataBaseName 数据库名  
15 - * tableName 表名  
16 - * columns 列  
17 - */  
18 - void insertData(TdTableDO table);  
19 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDataWriterServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.iot.service.tdengine;  
2 -  
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;  
4 -import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDataWriterMapper;  
5 -import jakarta.annotation.Resource;  
6 -import org.springframework.stereotype.Service;  
7 -  
8 -/**  
9 - * TD 引擎的数据写入 Service 实现类  
10 - */  
11 -@Service  
12 -public class TdEngineDataWriterServiceImpl implements TdEngineDataWriterService {  
13 -  
14 - @Resource  
15 - private TdEngineDataWriterMapper tdEngineDataWriterMapper;  
16 -  
17 - @Override  
18 - public void insertData(TdTableDO table) {  
19 - tdEngineDataWriterMapper.insertData(table);  
20 - }  
21 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDatabaseService.java deleted
1 -package cn.iocoder.yudao.module.iot.service.tdengine;  
2 -  
3 -/**  
4 - * TD 引擎的数据库 Service 接口  
5 - */  
6 -public interface TdEngineDatabaseService {  
7 -  
8 - /**  
9 - * 创建数据库  
10 - *  
11 - * @param dataBaseName 数据库名称  
12 - */  
13 - void createDatabase(String dataBaseName);  
14 -}  
15 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDatabaseServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.iot.service.tdengine;  
2 -  
3 -import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDatabaseMapper;  
4 -import jakarta.annotation.Resource;  
5 -import lombok.extern.slf4j.Slf4j;  
6 -import org.springframework.stereotype.Service;  
7 -  
8 -/**  
9 - * TD 引擎的数据库 Service 实现类  
10 - */  
11 -@Service  
12 -@Slf4j  
13 -public class TdEngineDatabaseServiceImpl implements TdEngineDatabaseService {  
14 -  
15 - @Resource  
16 - private TdEngineDatabaseMapper tdEngineDatabaseMapper;  
17 -  
18 - @Override  
19 - public void createDatabase(String dataBaseName) {  
20 - tdEngineDatabaseMapper.createDatabase(dataBaseName);  
21 - }  
22 -}  
23 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineQueryService.java deleted
1 -package cn.iocoder.yudao.module.iot.service.tdengine;  
2 -  
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;  
4 -  
5 -import java.util.List;  
6 -import java.util.Map;  
7 -  
8 -/**  
9 - * TD 引擎的查询 Service 接口  
10 - */  
11 -public interface TdEngineQueryService {  
12 -  
13 - /**  
14 - * 获取历史数据  
15 - *  
16 - * @param selectVisualDO 查询条件  
17 - * @return 历史数据列表  
18 - */  
19 - List<Map<String, Object>> getHistoryData(SelectVisualDO selectVisualDO);  
20 -  
21 - /**  
22 - * 获取历史数据条数  
23 - *  
24 - * @param selectVisualDO 查询条件  
25 - * @return 数据条数  
26 - */  
27 - Long getHistoryCount(SelectVisualDO selectVisualDO);  
28 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineQueryServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.iot.service.tdengine;  
2 -  
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;  
4 -import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineQueryMapper;  
5 -import jakarta.annotation.Resource;  
6 -import org.springframework.stereotype.Service;  
7 -  
8 -import java.util.List;  
9 -import java.util.Map;  
10 -  
11 -@Service  
12 -public class TdEngineQueryServiceImpl implements TdEngineQueryService {  
13 -  
14 - @Resource  
15 - private TdEngineQueryMapper tdEngineQueryMapper;  
16 -  
17 - @Override  
18 - public List<Map<String, Object>> getHistoryData(SelectVisualDO selectVisualDO) {  
19 - return tdEngineQueryMapper.getHistoryData(selectVisualDO);  
20 - }  
21 -  
22 - @Override  
23 - public Long getHistoryCount(SelectVisualDO selectVisualDO) {  
24 - return tdEngineQueryMapper.getHistoryCount(selectVisualDO);  
25 - }  
26 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineSuperTableService.java deleted
1 -package cn.iocoder.yudao.module.iot.service.tdengine;  
2 -  
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;  
4 -  
5 -import java.util.List;  
6 -import java.util.Map;  
7 -  
8 -/**  
9 - * TD 引擎的超级表 Service 接口  
10 - */  
11 -public interface TdEngineSuperTableService {  
12 -  
13 - /**  
14 - * 创建超级表  
15 - *  
16 - * @param superTable 超级表信息  
17 - * dataBaseName 数据库名称  
18 - * superTableName 超级表名称  
19 - * columns 列信息  
20 - * tags 标签信息  
21 - */  
22 - void createSuperTable(TdTableDO superTable);  
23 -  
24 - /**  
25 - * 查看超级表 - 显示当前数据库下的所有超级表信息  
26 - *  
27 - * @param superTable 超级表信息  
28 - * dataBaseName 数据库名称  
29 - * superTableName 超级表名称  
30 - */  
31 -  
32 - List<Map<String, Object>> showSuperTables(TdTableDO superTable);  
33 -  
34 - /**  
35 - * 查看超级表 - 获取超级表的结构信息  
36 - *  
37 - * @param superTable 超级表信息  
38 - * dataBaseName 数据库名称  
39 - * superTableName 超级表名称  
40 - */  
41 - List<Map<String, Object>> describeSuperTable(TdTableDO superTable);  
42 -  
43 - /**  
44 - * 修改超级表 - 增加列  
45 - *  
46 - * @param superTable 超级表信息  
47 - * dataBaseName 数据库名称  
48 - * superTableName 超级表名称  
49 - * column 列信息  
50 - */  
51 - void addColumnForSuperTable(TdTableDO superTable);  
52 -  
53 - /**  
54 - * 修改超级表 - 删除列  
55 - *  
56 - * @param superTable 超级表信息  
57 - * dataBaseName 数据库名称  
58 - * superTableName 超级表名称  
59 - * column 列信息  
60 - */  
61 - void dropColumnForSuperTable(TdTableDO superTable);  
62 -  
63 - /**  
64 - * 修改超级表 - 修改列宽  
65 - *  
66 - * @param superTable 超级表信息  
67 - * dataBaseName 数据库名称  
68 - * superTableName 超级表名称  
69 - * column 列信息  
70 - */  
71 - void modifyColumnWidthForSuperTable(TdTableDO superTable);  
72 -  
73 -  
74 - /**  
75 - * 修改超级表 - 为超级表添加标签  
76 - *  
77 - * @param superTable 超级表信息  
78 - * dataBaseName 数据库名称  
79 - * superTableName 超级表名称  
80 - * tag 标签信息  
81 - */  
82 - void addTagForSuperTable(TdTableDO superTable);  
83 -  
84 - /**  
85 - * 修改超级表 - 为超级表删除标签  
86 - *  
87 - * @param superTable 超级表信息  
88 - * dataBaseName 数据库名称  
89 - * superTableName 超级表名称  
90 - * tag 标签信息  
91 - */  
92 - void dropTagForSuperTable(TdTableDO superTable);  
93 -  
94 - /**  
95 - * 检查超级表是否存在  
96 - *  
97 - * @param superTable 超级表信息  
98 - * dataBaseName 数据库名称  
99 - * superTableName 超级表名称  
100 - * @return 超级表数量  
101 - */  
102 - Integer checkSuperTableExists(TdTableDO superTable);  
103 -  
104 - /**  
105 - * 为超级表添加列  
106 - *  
107 - * @param superTable 超级表信息  
108 - * dataBaseName 数据库名称  
109 - * superTableName 超级表名称  
110 - * columns 列信息  
111 - */  
112 - void addColumnsForSuperTable(TdTableDO superTable);  
113 -  
114 - /**  
115 - * 为超级表删除列  
116 - *  
117 - * @param superTable 超级表信息  
118 - * dataBaseName 数据库名称  
119 - * superTableName 超级表名称  
120 - * columns 列信息  
121 - */  
122 - void dropColumnsForSuperTable(TdTableDO superTable);  
123 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineSuperTableServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.iot.service.tdengine;  
2 -  
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;  
4 -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;  
5 -import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineSuperTableMapper;  
6 -import jakarta.annotation.Resource;  
7 -import lombok.extern.slf4j.Slf4j;  
8 -import org.springframework.stereotype.Service;  
9 -  
10 -import java.util.List;  
11 -import java.util.Map;  
12 -  
13 -/**  
14 - * TD 引擎的超级表 Service 实现类  
15 - */  
16 -@Slf4j  
17 -@Service  
18 -public class TdEngineSuperTableServiceImpl implements TdEngineSuperTableService {  
19 -  
20 - @Resource  
21 - private TdEngineSuperTableMapper tdEngineSuperTableMapper;  
22 -  
23 - @Override  
24 - public void createSuperTable(TdTableDO superTable) {  
25 - tdEngineSuperTableMapper.createSuperTable(superTable);  
26 - }  
27 -  
28 - @Override  
29 - public List<Map<String, Object>> showSuperTables(TdTableDO superTable) {  
30 - return tdEngineSuperTableMapper.showSuperTables(superTable);  
31 - }  
32 -  
33 - @Override  
34 - public List<Map<String, Object>> describeSuperTable(TdTableDO superTable) {  
35 - return tdEngineSuperTableMapper.describeSuperTable(superTable);  
36 - }  
37 -  
38 - @Override  
39 - public void addColumnForSuperTable(TdTableDO superTable) {  
40 - tdEngineSuperTableMapper.addColumnForSuperTable(superTable);  
41 - }  
42 -  
43 - @Override  
44 - public void dropColumnForSuperTable(TdTableDO superTable) {  
45 - tdEngineSuperTableMapper.dropColumnForSuperTable(superTable);  
46 - }  
47 -  
48 - @Override  
49 - public void modifyColumnWidthForSuperTable(TdTableDO superTable) {  
50 - tdEngineSuperTableMapper.modifyColumnWidthForSuperTable(superTable);  
51 - }  
52 -  
53 - @Override  
54 - public void addTagForSuperTable(TdTableDO superTable) {  
55 - tdEngineSuperTableMapper.addTagForSuperTable(superTable);  
56 - }  
57 -  
58 - @Override  
59 - public void dropTagForSuperTable(TdTableDO superTable) {  
60 - tdEngineSuperTableMapper.dropTagForSuperTable(superTable);  
61 - }  
62 -  
63 - @Override  
64 - public Integer checkSuperTableExists(TdTableDO superTable) {  
65 - List<Map<String, Object>> results = tdEngineSuperTableMapper.showSuperTables(superTable);  
66 - return results == null || results.isEmpty() ? 0 : results.size();  
67 - }  
68 -  
69 - @Override  
70 - public void addColumnsForSuperTable(TdTableDO superTable) {  
71 - for (TdFieldDO column : superTable.getColumns()) {  
72 - tdEngineSuperTableMapper.addColumnForSuperTable(TdTableDO.builder()  
73 - .dataBaseName(superTable.getDataBaseName())  
74 - .superTableName(superTable.getSuperTableName())  
75 - .column(column)  
76 - .build());  
77 - }  
78 - }  
79 -  
80 - @Override  
81 - public void dropColumnsForSuperTable(TdTableDO superTable) {  
82 - for (TdFieldDO column : superTable.getColumns()) {  
83 - tdEngineSuperTableMapper.dropColumnForSuperTable(TdTableDO.builder()  
84 - .dataBaseName(superTable.getDataBaseName())  
85 - .superTableName(superTable.getSuperTableName())  
86 - .column(column)  
87 - .build());  
88 - }  
89 - }  
90 -}  
91 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineTableService.java deleted
1 -package cn.iocoder.yudao.module.iot.service.tdengine;  
2 -  
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;  
4 -  
5 -/**  
6 - * TD 引擎的表 Service 接口  
7 - */  
8 -public interface TdEngineTableService {  
9 -  
10 - /**  
11 - * 创建表 - 创建超级表的子表  
12 - *  
13 - * @param table 表信息  
14 - * dataBaseName 数据库名称  
15 - * superTableName 超级表名称  
16 - * tableName 子表名称  
17 - * tags TAG 字段  
18 - */  
19 - void createTable(TdTableDO table);  
20 -  
21 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineTableServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.iot.service.tdengine;  
2 -  
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;  
4 -import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineTableMapper;  
5 -import jakarta.annotation.Resource;  
6 -import lombok.extern.slf4j.Slf4j;  
7 -import org.springframework.stereotype.Service;  
8 -  
9 -/**  
10 - * TD 引擎的表 Service 实现类  
11 - */  
12 -@Slf4j  
13 -@Service  
14 -public class TdEngineTableServiceImpl implements TdEngineTableService {  
15 -  
16 - @Resource  
17 - private TdEngineTableMapper tdEngineTableMapper;  
18 -  
19 - @Override  
20 - public void createTable(TdTableDO table) {  
21 - tdEngineTableMapper.createTable(table);  
22 - }  
23 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineSuperTableMapper.xml renamed to yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDDLMapper.xml
@@ -2,7 +2,12 @@ @@ -2,7 +2,12 @@
2 <!DOCTYPE mapper 2 <!DOCTYPE mapper
3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5 -<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineSuperTableMapper"> 5 +<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDDLMapper">
  6 +
  7 + <!-- 创建数据库 -->
  8 + <update id="createDatabase" parameterType="String">
  9 + CREATE DATABASE IF NOT EXISTS ${dataBaseName}
  10 + </update>
6 11
7 <!-- 创建超级表 --> 12 <!-- 创建超级表 -->
8 <update id="createSuperTable"> 13 <update id="createSuperTable">
@@ -68,4 +73,29 @@ @@ -68,4 +73,29 @@
68 ALTER STABLE ${dataBaseName}.${superTableName} DROP TAG ${tag.fieldName} 73 ALTER STABLE ${dataBaseName}.${superTableName} DROP TAG ${tag.fieldName}
69 </update> 74 </update>
70 75
71 -</mapper> 76 + <!-- 创建子表 -->
  77 + <update id="createTable">
  78 + CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}
  79 + USING ${dataBaseName}.${superTableName}
  80 + TAGS
  81 + <foreach item="item" collection="tags" separator=","
  82 + open="(" close=")">
  83 + #{item.fieldValue}
  84 + </foreach>
  85 + </update>
  86 +
  87 + <!-- 创建子表,带有 TAGS -->
  88 + <update id="createTableWithTags">
  89 + CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}
  90 + USING ${dataBaseName}.${superTableName}
  91 + <foreach item="item" collection="tags" separator="," open="(" close=")">
  92 + #{item.fieldName}
  93 + </foreach>
  94 + TAGS
  95 + <foreach item="item" collection="tags" separator=","
  96 + open="(" close=")">
  97 + #{item.fieldValue}
  98 + </foreach>
  99 + </update>
  100 +
  101 +</mapper>
72 \ No newline at end of file 102 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineQueryMapper.xml renamed to yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDMLMapper.xml
@@ -2,7 +2,21 @@ @@ -2,7 +2,21 @@
2 <!DOCTYPE mapper 2 <!DOCTYPE mapper
3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5 -<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineQueryMapper"> 5 +<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper">
  6 +
  7 + <!-- 插入数据 -->
  8 + <insert id="insertData">
  9 + INSERT INTO ${dataBaseName}.${tableName}
  10 + <foreach item="item" collection="columns" separator=","
  11 + open="(" close=")">
  12 + ${item.fieldName}
  13 + </foreach>
  14 + VALUES
  15 + <foreach item="item" collection="columns" separator=","
  16 + open="(" close=")">
  17 + #{item.fieldValue}
  18 + </foreach>
  19 + </insert>
6 20
7 <!-- 根据时间戳查询数据 --> 21 <!-- 根据时间戳查询数据 -->
8 <select id="selectByTimestamp" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO" 22 <select id="selectByTimestamp" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO"
@@ -12,7 +26,7 @@ @@ -12,7 +26,7 @@
12 </select> 26 </select>
13 27
14 <!-- 获取时间范围内的数据条数 --> 28 <!-- 获取时间范围内的数据条数 -->
15 - <select id="getCountByTimestamp" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO" 29 + <select id="selectCountByTimestamp" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO"
16 resultType="java.util.Map"> 30 resultType="java.util.Map">
17 SELECT COUNT(0) AS count 31 SELECT COUNT(0) AS count
18 FROM ${dataBaseName}.${tableName} 32 FROM ${dataBaseName}.${tableName}
@@ -20,14 +34,14 @@ @@ -20,14 +34,14 @@
20 </select> 34 </select>
21 35
22 <!-- 获取最新数据 --> 36 <!-- 获取最新数据 -->
23 - <select id="getLastData" resultType="java.util.Map"> 37 + <select id="selectOneLastData" resultType="java.util.Map">
24 SELECT LAST(time), * 38 SELECT LAST(time), *
25 FROM ${tableName} 39 FROM ${tableName}
26 WHERE device_id = #{deviceId} 40 WHERE device_id = #{deviceId}
27 </select> 41 </select>
28 42
29 <!-- 根据标签获取最新数据 --> 43 <!-- 根据标签获取最新数据 -->
30 - <select id="getLastDataByTags" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO" 44 + <select id="selectLastDataListByTags" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO"
31 resultType="Map"> 45 resultType="Map">
32 SELECT LAST(*) 46 SELECT LAST(*)
33 FROM ${dataBaseName}.${stableName} 47 FROM ${dataBaseName}.${stableName}
@@ -35,7 +49,7 @@ @@ -35,7 +49,7 @@
35 </select> 49 </select>
36 50
37 <!-- 获取历史数据 --> 51 <!-- 获取历史数据 -->
38 - <select id="getHistoryData" resultType="java.util.Map" 52 + <select id="selectHistoryDataList" resultType="java.util.Map"
39 parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO"> 53 parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
40 SELECT ${fieldName} AS data, time 54 SELECT ${fieldName} AS data, time
41 FROM ${dataBaseName}.${tableName} 55 FROM ${dataBaseName}.${tableName}
@@ -46,14 +60,14 @@ @@ -46,14 +60,14 @@
46 </select> 60 </select>
47 61
48 <!-- 获取实时数据 --> 62 <!-- 获取实时数据 -->
49 - <select id="getRealtimeData" resultType="java.util.Map" 63 + <select id="selectRealtimeDataList" resultType="java.util.Map"
50 parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO"> 64 parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
51 SELECT ${fieldName}, time 65 SELECT ${fieldName}, time
52 FROM ${dataBaseName}.${tableName} 66 FROM ${dataBaseName}.${tableName}
53 </select> 67 </select>
54 68
55 <!-- 获取聚合数据 --> 69 <!-- 获取聚合数据 -->
56 - <select id="getAggregateData" resultType="java.util.Map" 70 + <select id="selectAggregateDataList" resultType="java.util.Map"
57 parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO"> 71 parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
58 SELECT ${aggregate}(${fieldName}) 72 SELECT ${aggregate}(${fieldName})
59 FROM ${dataBaseName}.${tableName} 73 FROM ${dataBaseName}.${tableName}
@@ -62,11 +76,11 @@ @@ -62,11 +76,11 @@
62 </select> 76 </select>
63 77
64 <!-- 获取历史数据条数 --> 78 <!-- 获取历史数据条数 -->
65 - <select id="getHistoryCount" resultType="java.lang.Long"> 79 + <select id="selectHistoryCount" resultType="java.lang.Long">
66 SELECT COUNT(time) 80 SELECT COUNT(time)
67 FROM ${dataBaseName}.${tableName} 81 FROM ${dataBaseName}.${tableName}
68 WHERE time BETWEEN #{startTime} AND #{endTime} 82 WHERE time BETWEEN #{startTime} AND #{endTime}
69 AND ${fieldName} IS NOT NULL 83 AND ${fieldName} IS NOT NULL
70 </select> 84 </select>
71 85
72 -</mapper> 86 -</mapper>
  87 +</mapper>
73 \ No newline at end of file 88 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDataWriterMapper.xml deleted
1 -<?xml version="1.0" encoding="UTF-8"?>  
2 -<!DOCTYPE mapper  
3 - PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
4 - "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
5 -<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDataWriterMapper">  
6 -  
7 - <!-- 插入数据 -->  
8 - <insert id="insertData">  
9 - INSERT INTO ${dataBaseName}.${tableName}  
10 - <foreach item="item" collection="columns" separator=","  
11 - open="(" close=")">  
12 - ${item.fieldName}  
13 - </foreach>  
14 - VALUES  
15 - <foreach item="item" collection="columns" separator=","  
16 - open="(" close=")">  
17 - #{item.fieldValue}  
18 - </foreach>  
19 - </insert>  
20 -  
21 -</mapper>  
22 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDatabaseMapper.xml deleted
1 -<?xml version="1.0" encoding="UTF-8"?>  
2 -<!DOCTYPE mapper  
3 - PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
4 - "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
5 -<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDatabaseMapper">  
6 -  
7 - <!-- 创建数据库 -->  
8 - <update id="createDatabase" parameterType="String">  
9 - CREATE DATABASE IF NOT EXISTS ${dataBaseName}  
10 - </update>  
11 -  
12 -</mapper>  
13 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineTableMapper.xml deleted
1 -<?xml version="1.0" encoding="UTF-8"?>  
2 -<!DOCTYPE mapper  
3 - PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
4 - "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
5 -<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineTableMapper">  
6 -  
7 - <!-- 创建子表 -->  
8 - <update id="createTable">  
9 - CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}  
10 - USING ${dataBaseName}.${superTableName}  
11 - TAGS  
12 - <foreach item="item" collection="tags" separator=","  
13 - open="(" close=")">  
14 - #{item.fieldValue}  
15 - </foreach>  
16 - </update>  
17 -  
18 - <!-- 创建子表,带有 TAGS -->  
19 - <update id="createTableWithTags">  
20 - CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}  
21 - USING ${dataBaseName}.${superTableName}  
22 - <foreach item="item" collection="tags" separator="," open="(" close=")">  
23 - #{item.fieldName}  
24 - </foreach>  
25 - TAGS  
26 - <foreach item="item" collection="tags" separator=","  
27 - open="(" close=")">  
28 - #{item.fieldValue}  
29 - </foreach>  
30 - </update>  
31 -  
32 -</mapper>  
33 \ No newline at end of file 0 \ No newline at end of file