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

This commit is contained in:
安浩浩
2024-11-08 23:07:37 +08:00
parent d7b8cf547f
commit e3dcea9cb3
51 changed files with 1262 additions and 1442 deletions

View File

@@ -0,0 +1,22 @@
<?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.TdEngineDataWriterMapper">
<!-- 插入数据 -->
<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>
</mapper>

View File

@@ -0,0 +1,13 @@
<?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.TdEngineDatabaseMapper">
<!-- 创建数据库 -->
<update id="createDatabase" parameterType="String">
CREATE DATABASE IF NOT EXISTS ${dataBaseName}
</update>
</mapper>

View File

@@ -1,327 +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.TdEngineMapper">
<!-- TODO 对 $ 符号有安全要求的话,后期改为接口方式 -->
<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="schemaFields" separator=","
open="(" close=")" index="">
<if test="item.fieldName != null || item.fieldName != ''">
${item.fieldName}
</if>
<if test="item.dataType != null || item.dataType != ''">
<choose>
<when test="item.dataType == 'TIMESTAMP'">
TIMESTAMP
</when>
<when test="item.dataType == 'TINYINT'">
TINYINT
</when>
<when test="item.dataType == 'SMALLINT'">
SMALLINT
</when>
<when test="item.dataType == 'INT'">
INT
</when>
<when test="item.dataType == 'BIGINT'">
BIGINT
</when>
<when test="item.dataType == 'FLOAT'">
FLOAT
</when>
<when test="item.dataType == 'DOUBLE'">
DOUBLE
</when>
<when test="item.dataType == 'BINARY'">
BINARY
</when>
<when test="item.dataType == 'NCHAR'">
NCHAR
</when>
<when test="item.dataType == 'BOOL'">
BOOL
</when>
<when test="item.dataType == 'JSON'">
JSON
</when>
</choose>
</if>
<if test="item.dataLength > 0">
(
${item.dataLength}
)
</if>
</foreach>
TAGS
<!--tdEngine不支持动态tags里的数据类型只能使用choose标签比对-->
<foreach item="item" collection="tagsFields" separator=","
open="(" close=")" index="">
<if test="item.fieldName != null || item.fieldName != ''">
${item.fieldName}
</if>
<if test="item.dataType != null || item.dataType != ''">
<choose>
<when test="item.dataType == 'TIMESTAMP'">
TIMESTAMP
</when>
<when test="item.dataType == 'TINYINT'">
TINYINT
</when>
<when test="item.dataType == 'SMALLINT'">
SMALLINT
</when>
<when test="item.dataType == 'INT'">
INT
</when>
<when test="item.dataType == 'BIGINT'">
BIGINT
</when>
<when test="item.dataType == 'FLOAT'">
FLOAT
</when>
<when test="item.dataType == 'DOUBLE'">
DOUBLE
</when>
<when test="item.dataType == 'BINARY'">
BINARY
</when>
<when test="item.dataType == 'NCHAR'">
NCHAR
</when>
<when test="item.dataType == 'BOOL'">
BOOL
</when>
<when test="item.dataType == 'JSON'">
JSON
</when>
</choose>
</if>
<if test="item.dataLength > 0">
(
${item.dataLength}
)
</if>
</foreach>
</update>
<!-- CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...);-->
<update id="createTable">
CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}
USING ${dataBaseName}.${superTableName}
<foreach item="item" collection="tagsFieldValues" separator="," open="(" close=")">
${item.fieldName}
</foreach>
TAGS
<foreach item="item" collection="tagsFieldValues" separator="," open="(" close=")">
#{item.fieldValue}
</foreach>
</update>
<!-- insert into d1004 (ts, voltage, phase) values("2018-10-04 14:38:06", 223, 0.29) -->
<insert id="insertData">
INSERT INTO ${dataBaseName}.${tableName}
<foreach item="item" collection="schemaFieldValues" separator=","
open="(" close=")" index="">
${item.fieldName}
</foreach>
VALUES
<foreach item="item" collection="schemaFieldValues" separator=","
open="(" close=")" index="">
#{item.fieldValue}
</foreach>
</insert>
<select id="selectByTimestamp" parameterType="cn.iocoder.yudao.module.iot.domain.SelectDto"
resultType="Map">
select * from #{dataBaseName}.#{tableName}
<!--查询这里不能使用#{}占位符的方式使用这种方式tdEngine不识别为列名只能使用${}占位的方式-->
<!--因为tdEngine引擎一次只执行一条sql所以有效预防了sql的注入且该服务该接口为内部调用所以可以使用${}-->
where ${fieldName}
between #{startTime} and #{endTime}
</select>
<update id="addColumnForSuperTable">
ALTER STABLE ${dataBaseName}.${superTableName} ADD COLUMN
<if test="field.fieldName != null || field.fieldName != ''">
#{field.fieldName}
</if>
<if test="field.dataType != null || field.dataType != ''">
<choose>
<when test="field.dataType == 'TIMESTAMP'">
TIMESTAMP
</when>
<when test="field.dataType == 'TINYINT'">
TINYINT
</when>
<when test="field.dataType == 'SMALLINT'">
SMALLINT
</when>
<when test="field.dataType == 'INT'">
INT
</when>
<when test="field.dataType == 'BIGINT'">
BIGINT
</when>
<when test="field.dataType == 'FLOAT'">
FLOAT
</when>
<when test="field.dataType == 'DOUBLE'">
DOUBLE
</when>
<when test="field.dataType == 'BINARY'">
BINARY
</when>
<when test="field.dataType == 'NCHAR'">
NCHAR
</when>
<when test="field.dataType == 'BOOL'">
BOOL
</when>
<when test="field.dataType == 'JSON'">
JSON
</when>
</choose>
</if>
<if test="field.dataLength > 0">
(
#{field.dataLength}
)
</if>
</update>
<update id="dropColumnForSuperTable">
ALTER STABLE ${dataBaseName}.${superTableName} DROP COLUMN
<if test="field.fieldName != null || field.fieldName != ''">
#{field.fieldName}
</if>
</update>
<update id="addTagForSuperTable">
ALTER
STABLE
#{superTableName}
ADD
TAG
<if test="field.fieldName != null || fieldDO.fieldName != ''">
#{fieldDO.fieldName}
</if>
<if test="fieldDO.dataType != null || fieldDO.dataType != ''">
<choose>
<when test="fieldDO.dataType == 'timestamp'">
timestamp
</when>
<when test="fieldDO.dataType == 'tinyint'">
tinyint
</when>
<when test="fieldDO.dataType == 'smallint'">
smallint
</when>
<when test="fieldDO.dataType == 'int'">
int
</when>
<when test="fieldDO.dataType == 'bigint'">
bigint
</when>
<when test="fieldDO.dataType == 'float'">
float
</when>
<when test="fieldDO.dataType == 'double'">
double
</when>
<when test="fieldDO.dataType == 'binary'">
binary
</when>
<when test="fieldDO.dataType == 'nchar'">
nchar
</when>
<when test="fieldDO.dataType == 'bool'">
bool
</when>
<when test="fieldDO.dataType == 'json'">
json
</when>
</choose>
</if>
<if test="fieldDO.dataLength > 0">
(
#{fieldDO.dataLength}
)
</if>
</update>
<update id="dropTagForSuperTable">
ALTER
STABLE
#{superTableName}
DROP
TAG
<if test="fieldsVo.fieldName != null || fieldsVo.fieldName != ''">
#{fieldsVo.fieldName}
</if>
</update>
<select id="getCountByTimestamp" parameterType="cn.iocoder.yudao.module.iot.domain.SelectDto"
resultType="java.util.Map">
SELECT count(0) AS count
FROM #{dataBaseName}.#{tableName}
WHERE ${fieldName} BETWEEN #{startTime} AND #{endTime}
</select>
<select id="showSuperTables" resultType="java.util.Map">
SHOW ${dataBaseName}.STABLES LIKE '${superTableName}'
</select>
<select id="getLastData" resultType="java.util.Map">
select last(time), *
from #{tableName}
where device_id = #{deviceId}
</select>
<select id="getLastDataByTags" parameterType="cn.iocoder.yudao.module.iot.domain.TagsSelectDao"
resultType="Map">
select last(*)
from #{dataBaseName}.#{stableName}
group by ${tagsName}
</select>
<select id="getHistoryData" resultType="java.util.Map"
parameterType="cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto">
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="getRealtimeData" resultType="java.util.Map"
parameterType="cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto">
SELECT #{fieldName}, time
FROM #{dataBaseName}.#{tableName}
</select>
<select id="getAggregateData" resultType="java.util.Map"
parameterType="cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto">
SELECT #{aggregate}(${fieldName})
FROM #{dataBaseName}.#{tableName}
WHERE ts BETWEEN #{startTime} AND #{endTime} interval (${interval})
LIMIT #{num}
</select>
<select id="describeSuperTable" resultType="java.util.Map">
DESCRIBE ${dataBaseName}.${superTableName}
</select>
<select id="getHistoryCount" resultType="java.lang.Long">
SELECT count(time)
FROM ${dataBaseName}.${tableName}
WHERE time BETWEEN #{startTime} AND #{endTime}
AND ${fieldName} IS NOT NULL
</select>
</mapper>

View File

@@ -0,0 +1,73 @@
<?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.TdEngineQueryMapper">
<!-- 根据时间戳查询数据 -->
<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="getCountByTimestamp" 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="getLastData" resultType="java.util.Map">
SELECT LAST(time), *
FROM ${tableName}
WHERE device_id = #{deviceId}
</select>
<!-- 根据标签获取最新数据 -->
<select id="getLastDataByTags" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO"
resultType="Map">
SELECT LAST(*)
FROM ${dataBaseName}.${stableName}
GROUP BY ${tagsName}
</select>
<!-- 获取历史数据 -->
<select id="getHistoryData" 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="getRealtimeData" resultType="java.util.Map"
parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
SELECT ${fieldName}, time
FROM ${dataBaseName}.${tableName}
</select>
<!-- 获取聚合数据 -->
<select id="getAggregateData" 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="getHistoryCount" resultType="java.lang.Long">
SELECT COUNT(time)
FROM ${dataBaseName}.${tableName}
WHERE time BETWEEN #{startTime} AND #{endTime}
AND ${fieldName} IS NOT NULL
</select>
</mapper>

View File

@@ -0,0 +1,72 @@
<?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.TdEngineSuperTableMapper">
<!-- 创建超级表 -->
<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>
</mapper>

View File

@@ -0,0 +1,33 @@
<?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.TdEngineTableMapper">
<!-- 创建子表 -->
<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>