IoTDB 是针对时间序列数据收集、存储与分析一体化的数据管理引擎。它具有体量轻、性能高、易使用的特点,完美对接 Hadoop 与 Spark 生态,适用于工业物联网应用中海量时间序列数据高速写入和复杂分析查询的需求。
https://iotdb.apache.org/zh/UserGuide/V0.13.x/QuickStart/WayToGetIoTDB.html
<dependencies>
<!--iotdb-->
<dependency>
<groupId>org.apache.iotdb</groupId>
<artifactId>iotdb-session</artifactId>
<version>0.13.0</version>
</dependency>
</dependencies>
package com.wang.learn.cloudiot.config;
import lombok.extern.slf4j.Slf4j;
import org.apache.iotdb.session.Session;
import org.apache.iotdb.session.pool.SessionPool;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author wang
* Date 2022/5/24 10:34
*/
@Slf4j
@Configuration
public class IotDbConfig {
@Value("${spring.iotdb.username:root}")
private String username;
@Value("${spring.iotdb.password:root}")
private String password;
@Value("${spring.iotdb.ip:127.0.0.1}")
private String ip;
@Value("${spring.iotdb.port:6667}")
private int port;
@Value("${spring.iotdb.maxSize:10}")
private int maxSize;
@Bean
public SessionPool sessionPool() {
return new SessionPool.Builder()
.host(ip)
.port(port)
.user(username)
.password(password)
.maxSize(100)
.build();
}
}
package com.wang.learn.cloudiot.controller;
import com.wang.learn.cloudiot.pojo.param.SaveIotParam;
import com.wang.learn.cloudiot.pojo.param.SearchIotParam;
import com.wang.learn.cloudiot.service.SessionPoolService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author wang
* Date 2022/5/24 10:34
*/
@Slf4j
@RestController
@RequestMapping("/session")
@RequiredArgsConstructor
public class SessionController {
final SessionPoolService sessionPoolService;
@PostMapping("/insert")
public String insert(@RequestBody SaveIotParam data) throws Exception {
sessionPoolService.insertTablet();
return "SUCCESS";
}
@PostMapping("/list")
public List<Object> list(@RequestBody SearchIotParam data) throws Exception {
return sessionPoolService.selectByParam(data);
}
@PostMapping("/delete")
public void delete(@RequestBody SearchIotParam data) throws Exception {
sessionPoolService.deleteByParam(data);
}
}
package com.wang.learn.cloudiot.service;
import com.wang.learn.cloudiot.pojo.param.SearchIotParam;
import lombok.RequiredArgsConstructor;
import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.StatementExecutionException;
import org.apache.iotdb.session.pool.SessionDataSetWrapper;
import org.apache.iotdb.session.pool.SessionPool;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.read.common.Field;
import org.apache.iotdb.tsfile.read.common.RowRecord;
import org.apache.iotdb.tsfile.write.record.Tablet;
import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* ClassName SessionPoolService
*
* @author wang
* Date 2022/5/24 14:11
*/
@Service
@RequiredArgsConstructor
public class SessionPoolService {
final SessionPool sessionPool;
public void insertTablet() throws IoTDBConnectionException, StatementExecutionException {
/*
* A Tablet example:
* device1
* time s1, s2, s3
* 1, 1, 1, 1
* 2, 2, 2, 2
* 3, 3, 3, 3
*/
// The schema of measurements of one device
// only measurementId and data type in MeasurementSchema take effects in Tablet
List<MeasurementSchema> schemaList = new ArrayList<>();
schemaList.add(new MeasurementSchema("s1", TSDataType.INT64));
schemaList.add(new MeasurementSchema("s2", TSDataType.INT64));
schemaList.add(new MeasurementSchema("s3", TSDataType.INT64));
Tablet tablet = new Tablet("root.1111.vehicle.9sahga9g0asiker9sgjjakclw1law", schemaList, 100);
// Method 1 to add tablet data
long timestamp = System.currentTimeMillis();
for (long row = 0; row < 10; row++) {
int rowIndex = tablet.rowSize++;
tablet.addTimestamp(rowIndex, timestamp);
// 封装列
for (int s = 0; s < 3; s++) {
long value = new Random().nextLong();
tablet.addValue(schemaList.get(s).getMeasurementId(), rowIndex, value);
}
timestamp++;
}
sessionPool.insertTablet(tablet, true);
}
/**
* insert the data of a device. For each timestamp, the number of measurements is the same.
*
* <p>Users need to control the count of Tablet and write a batch when it reaches the maxBatchSize
*/
public List<Object> selectByParam(SearchIotParam data) throws Exception {
// TODO 时间序列是否要明确?对应产品上报的数据字段是否确定
String sql = buildQuerySql(data);
SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement("select * from " + sql);
List<Object> groupList = new ArrayList<>();
while (sessionDataSetWrapper.hasNext()) {
RowRecord next = sessionDataSetWrapper.next();
List<Field> fields = next.getFields();
for (Field field : fields) {
groupList.add(field.getStringValue());
}
}
return groupList;
}
/**
* insert the data of a device. For each timestamp, the number of measurements is the same.
*
* <p>Users need to control the count of Tablet and write a batch when it reaches the maxBatchSize
*/
public void deleteByParam(SearchIotParam data) throws Exception {
// TODO 时间序列是否要明确?对应产品上报的数据字段是否确定
StringBuffer stringBuffer = buildCommonStr(data).append(".*");
sessionPool.deleteData(Collections.singletonList(stringBuffer.toString()), data.getStartTime(), data.getEndTime());
}
private String buildQuerySql(SearchIotParam data) {
StringBuffer sb = buildCommonStr(data);
if (Objects.nonNull(data.getStartTime()) && Objects.nonNull(data.getEndTime())) {
sb.append(" where time >= ")
.append(data.getStartTime())
.append(" and time < ").append(data.getEndTime())
.append(" limit 10 offset 20 ");
}
return sb.toString();
}
private StringBuffer buildCommonStr(SearchIotParam data) {
StringBuffer sb = new StringBuffer("root");
sb.append(".")
.append(data.getOrgCode())
.append(".")
.append(data.getProductId())
.append(".")
.append(data.getDeviceId());
return sb;
}
}
package com.wang.learn.cloudiot.pojo.param;
import lombok.Data;
/**
* ClassName RequestParam
*
* @author wang
* Date 2022/5/24 10:34
*/
@Data
public class SearchIotParam {
private String orgCode;
private String productId;
private String deviceId;
private Long startTime;
private Long endTime;
}
完整代码示例
https://gitee.com/wangLi1997/spring-cloud-learn/tree/master/cloud-iot