
TDengine Java 连接器入门指南
一、什么是 TDengine Java 连接器?
TDengine Java 连接器(taos-jdbcdriver)是一个让 Java 程序能够连接和操作 TDengine 时序数据库的工具包。就像你需要一把钥匙才能打开门一样,Java 程序需要这个连接器才能访问 TDengine 数据库中的数据。
简单来说:它是 Java 应用程序和 TDengine 数据库之间的"桥梁"。
连接器的两种类型
TDengine 提供了两种连接方式,就像去一个地方可以选择不同的交通工具:
-
原生连接(Native Connection)
- 速度快,性能好
- 需要在本地安装 TDengine 客户端驱动
- 适合:服务器端应用、性能要求高的场景
-
WebSocket 连接
- 无需安装客户端驱动,开箱即用
- 可以跨平台使用,只要能运行 Java 就行
- 适合:云环境、客户端应用、快速开发测试
二、Java 连接器能做什么?
使用 TDengine Java 连接器,你可以:
✅ 数据查询 :从数据库读取数据
✅ 数据写入 :向数据库插入新数据
✅ 数据更新 :修改数据库中的数据
✅ 数据库管理 :创建/删除数据库、表等
✅ 批量操作 :一次性插入大量数据,提高效率
✅ 参数绑定写入 :高性能的数据写入方式
✅ 数据订阅:实时接收数据变化通知
三、开始使用前的准备
1. 环境要求
- Java 版本:JDK 8 或更高版本
- JDBC 版本:支持 JDBC 4.2 及以上
- TDengine 服务器:需要有一个运行中的 TDengine 实例
2. 添加依赖
在你的 Java 项目中添加 TDengine JDBC 驱动依赖:
Maven 项目
在 pom.xml 文件中添加:
xml
<dependency>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>3.7.8</version>
</dependency>
Gradle 项目
在 build.gradle 文件中添加:
gradle
implementation 'com.taosdata.jdbc:taos-jdbcdriver:3.7.8'
四、快速上手示例
示例 1:使用 WebSocket 连接(推荐新手)
WebSocket 连接最简单,不需要安装额外的客户端驱动。
java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
public class QuickStartWebSocket {
// 数据库连接信息
private static final String HOST = "localhost"; // TDengine 服务器地址
private static final String PORT = "6041"; // WebSocket 端口(默认 6041)
private static final String DATABASE = "test"; // 数据库名
private static final String USER = "root"; // 用户名
private static final String PASSWORD = "taosdata"; // 密码
public static void main(String[] args) {
// 1. 构建连接 URL
String jdbcUrl = String.format(
"jdbc:TAOS-WS://%s:%s/%s?user=%s&password=%s",
HOST, PORT, DATABASE, USER, PASSWORD
);
// 2. 获取连接
try (Connection conn = DriverManager.getConnection(jdbcUrl)) {
System.out.println("✅ 连接成功!");
// 3. 创建 Statement 对象
try (Statement stmt = conn.createStatement()) {
// 4. 创建数据库(如果不存在)
stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS test");
System.out.println("✅ 数据库创建成功");
// 5. 使用数据库
stmt.executeUpdate("USE test");
// 6. 创建超级表
stmt.executeUpdate(
"CREATE STABLE IF NOT EXISTS meters " +
"(ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) " +
"TAGS (groupid INT, location BINARY(24))"
);
System.out.println("✅ 超级表创建成功");
// 7. 插入数据
stmt.executeUpdate(
"INSERT INTO d1001 USING meters TAGS(1, '北京.朝阳') " +
"VALUES (NOW, 10.2, 219, 0.32)"
);
System.out.println("✅ 数据插入成功");
// 8. 查询数据
ResultSet rs = stmt.executeQuery("SELECT * FROM meters");
System.out.println("\n📊 查询结果:");
while (rs.next()) {
System.out.printf(
"时间: %s, 电流: %.2f, 电压: %d, 相位: %.2f%n",
rs.getTimestamp("ts"),
rs.getFloat("current"),
rs.getInt("voltage"),
rs.getFloat("phase")
);
}
rs.close();
}
} catch (SQLException e) {
System.err.println("❌ 错误: " + e.getMessage());
e.printStackTrace();
}
}
}
示例 2:使用原生连接
如果你已经安装了 TDengine 客户端驱动,可以使用原生连接获得更好的性能。
java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.SQLException;
public class QuickStartNative {
public static void main(String[] args) {
// 原生连接 URL(端口默认 6030)
String jdbcUrl = "jdbc:TAOS://localhost:6030/test?user=root&password=taosdata";
try (Connection conn = DriverManager.getConnection(jdbcUrl);
Statement stmt = conn.createStatement()) {
System.out.println("✅ 原生连接成功!");
// 执行 SQL 操作...
stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS test");
} catch (SQLException e) {
System.err.println("❌ 错误: " + e.getMessage());
e.printStackTrace();
}
}
}
示例 3:批量插入数据
批量插入可以大幅提升写入性能。
java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.SQLException;
public class BatchInsertDemo {
public static void main(String[] args) {
String jdbcUrl = "jdbc:TAOS-WS://localhost:6041/test?user=root&password=taosdata";
try (Connection conn = DriverManager.getConnection(jdbcUrl);
Statement stmt = conn.createStatement()) {
// 准备数据库和表
stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS test");
stmt.executeUpdate("USE test");
stmt.executeUpdate(
"CREATE STABLE IF NOT EXISTS sensors " +
"(ts TIMESTAMP, temperature FLOAT, humidity FLOAT) " +
"TAGS (device_id INT, location BINARY(32))"
);
// 批量插入多条数据
StringBuilder sql = new StringBuilder("INSERT INTO ");
// 向设备 1001 插入 3 条数据
sql.append("t1001 USING sensors TAGS(1001, '车间A') VALUES ")
.append("(NOW, 25.5, 60.2) ")
.append("(NOW+1s, 25.6, 60.3) ")
.append("(NOW+2s, 25.7, 60.1) ");
// 向设备 1002 插入 3 条数据
sql.append("t1002 USING sensors TAGS(1002, '车间B') VALUES ")
.append("(NOW, 26.1, 65.5) ")
.append("(NOW+1s, 26.2, 65.7) ")
.append("(NOW+2s, 26.0, 65.3)");
int affected = stmt.executeUpdate(sql.toString());
System.out.printf("✅ 成功插入 %d 条数据%n", affected);
} catch (SQLException e) {
System.err.println("❌ 错误: " + e.getMessage());
e.printStackTrace();
}
}
}
示例 4:使用 PreparedStatement 参数绑定
参数绑定是高性能写入的最佳方式。
java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
public class PreparedStatementDemo {
public static void main(String[] args) {
String jdbcUrl = "jdbc:TAOS-WS://localhost:6041/test?user=root&password=taosdata";
try (Connection conn = DriverManager.getConnection(jdbcUrl)) {
// 准备数据库和表
try (Statement stmt = conn.createStatement()) {
stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS test");
stmt.executeUpdate("USE test");
stmt.executeUpdate(
"CREATE STABLE IF NOT EXISTS weather " +
"(ts TIMESTAMP, temperature FLOAT, humidity INT) " +
"TAGS (location BINARY(32))"
);
}
// 使用 PreparedStatement 插入数据
String insertSql = "INSERT INTO ? USING weather TAGS(?) VALUES(?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) {
// 循环插入 10 条数据
for (int i = 0; i < 10; i++) {
// 设置表名
pstmt.setString(1, "weather_" + i);
// 设置 tag 值
pstmt.setString(2, "城市" + i);
// 设置列值
pstmt.setTimestamp(3, new Timestamp(System.currentTimeMillis() + i * 1000));
pstmt.setFloat(4, 20.0f + i);
pstmt.setInt(5, 50 + i);
// 添加到批处理
pstmt.addBatch();
}
// 执行批处理
int[] results = pstmt.executeBatch();
System.out.printf("✅ 批量插入完成,共 %d 条数据%n", results.length);
}
} catch (SQLException e) {
System.err.println("❌ 错误: " + e.getMessage());
e.printStackTrace();
}
}
}
示例 5:查询数据并处理结果
java
import java.sql.*;
public class QueryDemo {
public static void main(String[] args) {
String jdbcUrl = "jdbc:TAOS-WS://localhost:6041/test?user=root&password=taosdata";
try (Connection conn = DriverManager.getConnection(jdbcUrl);
Statement stmt = conn.createStatement()) {
// 执行查询
String query = "SELECT ts, temperature, humidity, location " +
"FROM weather " +
"WHERE ts >= NOW - 1h " +
"ORDER BY ts DESC " +
"LIMIT 10";
ResultSet rs = stmt.executeQuery(query);
// 打印表头
System.out.println("═══════════════════════════════════════════════════");
System.out.printf("%-25s %-12s %-12s %-15s%n",
"时间", "温度", "湿度", "位置");
System.out.println("═══════════════════════════════════════════════════");
// 遍历结果集
while (rs.next()) {
Timestamp ts = rs.getTimestamp("ts");
float temperature = rs.getFloat("temperature");
int humidity = rs.getInt("humidity");
String location = rs.getString("location");
System.out.printf("%-25s %-12.2f %-12d %-15s%n",
ts, temperature, humidity, location);
}
System.out.println("═══════════════════════════════════════════════════");
rs.close();
} catch (SQLException e) {
System.err.println("❌ 错误: " + e.getMessage());
e.printStackTrace();
}
}
}
五、连接配置参数说明
WebSocket 连接 URL 格式
jdbc:TAOS-WS://[host]:[port]/[database]?[参数1=值1&参数2=值2...]
原生连接 URL 格式
jdbc:TAOS://[host]:[port]/[database]?[参数1=值1&参数2=值2...]
常用配置参数
| 参数名 | 说明 | 默认值 | 示例 |
|---|---|---|---|
| user | 用户名 | root | user=root |
| password | 密码 | taosdata | password=taosdata |
| charset | 字符集 | 系统字符集 | charset=UTF-8 |
| timezone | 时区 | 系统时区 | timezone=Asia/Shanghai |
| batchErrorIgnore | 批量操作时是否忽略错误 | false | batchErrorIgnore=true |
| useSSL | 是否使用 SSL(仅 WebSocket) | false | useSSL=true |
| enableCompression | 启用压缩(仅 WebSocket) | false | enableCompression=true |
| varcharAsString | VARCHAR 映射为 String(仅 WebSocket) | false | varcharAsString=true |
配置示例
java
// 带多个参数的连接 URL
String jdbcUrl = "jdbc:TAOS-WS://localhost:6041/test" +
"?user=root" +
"&password=taosdata" +
"&timezone=Asia/Shanghai" +
"&enableCompression=true" +
"&varcharAsString=true";
六、数据类型映射
了解 TDengine 数据类型与 Java 类型的对应关系:
| TDengine 类型 | Java 类型 | 说明 |
|---|---|---|
| TIMESTAMP | java.sql.Timestamp | 时间戳 |
| BOOL | java.lang.Boolean | 布尔值 |
| TINYINT | java.lang.Byte | 8位整数 |
| SMALLINT | java.lang.Short | 16位整数 |
| INT | java.lang.Integer | 32位整数 |
| BIGINT | java.lang.Long | 64位整数 |
| FLOAT | java.lang.Float | 单精度浮点数 |
| DOUBLE | java.lang.Double | 双精度浮点数 |
| BINARY | byte[] | 二进制数据 |
| NCHAR | java.lang.String | 字符串(Unicode) |
| VARCHAR | byte[] 或 String | 变长字符串 |
七、异常处理最佳实践
java
import java.sql.*;
public class ExceptionHandlingDemo {
public static void main(String[] args) {
String jdbcUrl = "jdbc:TAOS-WS://localhost:6041/test?user=root&password=taosdata";
try (Connection conn = DriverManager.getConnection(jdbcUrl);
Statement stmt = conn.createStatement()) {
// 执行 SQL
stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS test");
} catch (SQLException e) {
// 获取错误信息
System.err.println("错误代码: " + e.getErrorCode());
System.err.println("SQL 状态: " + e.getSQLState());
System.err.println("错误信息: " + e.getMessage());
// 打印堆栈跟踪(开发调试用)
e.printStackTrace();
// 根据错误码处理不同的异常
switch (e.getErrorCode()) {
case 0x2301: // 数据库不存在
System.err.println("数据库不存在,请先创建数据库");
break;
case 0x2603: // 表已存在
System.err.println("表已经存在");
break;
default:
System.err.println("未知错误");
}
}
}
}
八、常见问题和解决方案
问题 1:连接失败
症状:无法连接到 TDengine 服务器
检查项:
- ✅ TDengine 服务是否正在运行?
- ✅ 主机地址和端口是否正确?(WebSocket: 6041, 原生: 6030)
- ✅ 用户名和密码是否正确?
- ✅ 防火墙是否允许访问?
问题 2:java.lang.UnsatisfiedLinkError: no taos in java.library.path
原因:使用原生连接但未安装客户端驱动
解决方案:
- 安装 TDengine 客户端
- 或改用 WebSocket 连接(推荐)
问题 3:批量插入性能不佳
原因 :使用了 addBatch() + executeBatch() 方式
优化方案:
- 在一条 INSERT 语句中拼接多个 VALUES
- 使用 PreparedStatement 参数绑定
- 使用多线程并发插入
问题 4:时区问题
症状:查询出的时间与预期不符
解决方案:
java
// 在连接 URL 中指定时区
String jdbcUrl = "jdbc:TAOS-WS://localhost:6041/test" +
"?user=root&password=taosdata" +
"&timezone=Asia/Shanghai";
九、进阶主题
1. 连接池使用
在生产环境中,建议使用连接池来管理数据库连接,提高性能。
java
// 使用 HikariCP 连接池
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:TAOS-WS://localhost:6041/test");
config.setUsername("root");
config.setPassword("taosdata");
config.setMaximumPoolSize(10);
config.setMinimumIdle(5);
HikariDataSource dataSource = new HikariDataSource(config);
// 从连接池获取连接
try (Connection conn = dataSource.getConnection()) {
// 执行数据库操作...
}
2. Spring Boot 集成
在 Spring Boot 项目中使用 TDengine:
yaml
# application.yml
spring:
datasource:
driver-class-name: com.taosdata.jdbc.ws.WebSocketDriver
url: jdbc:TAOS-WS://localhost:6041/test
username: root
password: taosdata
3. 数据订阅
实时接收数据变化:
java
// 订阅功能示例(需要单独学习)
Properties config = new Properties();
config.setProperty("bootstrap.servers", "localhost:6041");
config.setProperty("value.deserializer", "com.taosdata.jdbc.tmq.ConsumerTest");
config.setProperty("group.id", "group1");
TaosConsumer<ResultSet> consumer = new TaosConsumer<>(config);
// 订阅主题...
十、学习资源
关于 TDengine
TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。