# SpringBoot-IoTDB
**Repository Path**: aberz/spring-boot-io-tdb
## Basic Information
- **Project Name**: SpringBoot-IoTDB
- **Description**: 采用SpringBoot操作IoT数据库
- **Primary Language**: Java
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 20
- **Forks**: 5
- **Created**: 2021-11-22
- **Last Updated**: 2025-06-17
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
Spring-Boot-IoTDB
---
1. 本文主要描述了使用JDBC连接IoTDB完成CPU数据的实时采集,并提供了REST API查询和Grafana可视化查看的过程
2. 项目代码地址:https://github.com/stormbroken/Spring-Boot-IoTDB
- [1. 实验环境](#1-实验环境)
- [2. 项目环境接口说明](#2-项目环境接口说明)
- [2.1. 连接测试](#21-连接测试)
- [2.2. 系统数据采样](#22-系统数据采样)
- [3. 配置文件说明](#3-配置文件说明)
- [4. 核心代码说明](#4-核心代码说明)
- [4.1. POJO类:MySystemInfo](#41-pojo类mysysteminfo)
- [4.2. 连接JDBC:IoTDBService](#42-连接jdbciotdbservice)
- [4.3. 定时采样任务](#43-定时采样任务)
- [5. 与Grafana连接](#5-与grafana连接)
# 1. 实验环境
1. 操作系统:Windows 10
2. JDK版本:1.8
3. Spring Boot:2.5.2
4. IoTDB 版本:0.12.1,启动端口6667
5. Grafana 版本:8.0.4,启动端口8081
# 2. 项目环境接口说明
## 2.1. 连接测试

1. /test/health:检查应用心跳
2. /test/jdbcCreateTest:创建测试用存储组
3. /test/jdbcInsertTest:创建测试插入数据
4. /test/jdbcQueryTest:创建测试查询接口
5. /test/jdbcDeleteTest:删除测试用存储组
6. 上述接口在测试过程中可以按照字面顺序执行查看返回结果和报错。
## 2.2. 系统数据采样

1. /system/init:初始化创建系统采样用存储组
2. /system/findAll:查询所有的采样结果数据
3. /system/delete:删除系统采样用存储组
# 3. 配置文件说明
1. 核心配置文件为pom.xml文件,请进入Github项目查看具体配置。
2. 其中需要注意iotdb-jdbc不要使用0.13版本,会报错失败,本项目使用的为0.12.1版本。
```xml
org.apache.iotdb
iotdb-jdbc
0.12.1
```
# 4. 核心代码说明
## 4.1. POJO类:MySystemInfo
```java
@Data
public class MySystemInfo {
// 内存使用率
Double memoryUsage;
// CPU使用率
Double cpuUsage;
// 磁盘使用率
Double diskUsage;
// 采样时间 ms
Long time;
}
```
## 4.2. 连接JDBC:IoTDBService
1. 该服务主要负责将Spring应用通过JDBC与IoTDB进行连接
2. 遇到的问题
1. Query的结果集输出报错SQLException(400):请检查是否在输出之前将Statement或Connection关闭
2. 请在使用完成ResultSet后将其关闭,避免过多未关闭连接降低查询性能。
```java
/**
* @Author stormbroken
* Create by 2021/07/07
* @Version 1.0
**/
@Service
public class IoTDBService {
@Value("${iotdb.url}")
String url;
@Value("${iotdb.username}")
String username;
@Value("${iotdb.password}")
String password;
/**
* 建立连接
*/
Connection connection;
public void getConnection() throws ClassNotFoundException, SQLException {
if(connection == null){
synchronized (this){
if(connection == null){
Class.forName("org.apache.iotdb.jdbc.IoTDBDriver");
connection = DriverManager.getConnection(url, username, password);
}
}
}
}
/**
* 新建Statement后执行语句
* @param statementStr
* @return
* @throws ClassNotFoundException
* @throws SQLException
*/
public boolean executeStatement(String statementStr)
throws ClassNotFoundException, SQLException{
Statement statement = getStatement();
return statement.execute(statementStr);
}
/**
* 新建Statement后执行一批语句
* @param statements
* @return
* @throws ClassNotFoundException
* @throws SQLException
*/
public void executeStatements(List statements)
throws ClassNotFoundException, SQLException{
Statement statement = getStatement();
for(String statementStr: statements){
statement.addBatch(statementStr);
}
statement.executeBatch();
}
/**
* 按照查询语句进行查询
* @param query
* @param fetchSize
* @return
* @throws ClassNotFoundException
* @throws SQLException
*/
public ResultSet executeQuery(String query, Integer fetchSize)
throws ClassNotFoundException, SQLException{
Statement statement = getStatement();
statement.setFetchSize(fetchSize);
return statement.executeQuery(query);
}
/**
* 插入一条系统数据
* @param statement
* @param mySystemInfo
* @return
* @throws ClassNotFoundException
* @throws SQLException
*/
public boolean insertSystemInfo(String statement, MySystemInfo mySystemInfo)
throws ClassNotFoundException, SQLException{
PreparedStatement preparedStatement = getPreparedStatement(statement);
preparedStatement.setLong(1, mySystemInfo.getTime());
preparedStatement.setDouble(2, mySystemInfo.getMemoryUsage());
preparedStatement.setDouble(3, mySystemInfo.getCpuUsage());
preparedStatement.setDouble(4, mySystemInfo.getDiskUsage());
return preparedStatement.execute();
}
/**
* 输出结果集
* @param resultSet
* @throws SQLException
*/
public String outputResult(ResultSet resultSet) throws SQLException {
StringBuilder stringBuilder = new StringBuilder();
if (resultSet != null) {
stringBuilder.append("--------------------------");
final ResultSetMetaData metaData = resultSet.getMetaData();
final int columnCount = metaData.getColumnCount();
for (int i = 0; i < columnCount; i++) {
stringBuilder.append(metaData.getColumnLabel(i + 1));
stringBuilder.append(" ");
}
stringBuilder.append("\n");
while (resultSet. next()) {
StringBuilder builder = new StringBuilder();
for (int i = 1; ; i++) {
builder.append(resultSet.getString(i));
if (i < columnCount) {
builder.append(", ");
} else {
builder.append("\n");
break;
}
}
stringBuilder.append(builder);
}
stringBuilder.append("--------------------------\n\n");
}
return stringBuilder.toString();
}
/**
* 获取 Statement 进行执行
* @return
* @throws ClassNotFoundException
* @throws SQLException
*/
private Statement getStatement()
throws ClassNotFoundException, SQLException{
getConnection();
return connection.createStatement();
}
/**
* 获取 PreparedStatement 进行执行
* @param statement
* @return
* @throws ClassNotFoundException
* @throws SQLException
*/
private PreparedStatement getPreparedStatement(String statement)
throws ClassNotFoundException, SQLException{
getConnection();
return connection.prepareStatement(statement);
}
}
```
## 4.3. 定时采样任务
1. 本部分使用了定时任务,1秒钟采样一次。
2. 采样结束后进行写库。
```java
@Scheduled(cron = "* * * * * *")
public void updateInfo() throws ClassNotFoundException, SQLException {
MySystemInfo mySystemInfo = new MySystemInfo();
mySystemInfo.setCpuUsage(getCpuUsage());
mySystemInfo.setDiskUsage(getDiskUsage());
mySystemInfo.setMemoryUsage(getMemoryUsage());
mySystemInfo.setTime(System.currentTimeMillis());
systemService.insert(mySystemInfo);
}
```
# 5. 与Grafana连接
1. 参考官网文献完成配置
2. 将Grafana和IoTDB完成连接需要按如下操作
1. 安装并启动Grafana
2. 安装并启动IoTDB
3. 安装Grafana插件simple-json,并重启Grafana
4. 启动Grafana连接器
5. 启动已经编写好的Spring应用程序
6. 进入Grafana按照用户手册配置Data Source创建对应面板,最终效果如下所示:

