TDengine JAVA 语言连接器入门指南

TDengine Java 连接器入门指南

一、什么是 TDengine Java 连接器?

TDengine Java 连接器(taos-jdbcdriver)是一个让 Java 程序能够连接和操作 TDengine 时序数据库的工具包。就像你需要一把钥匙才能打开门一样,Java 程序需要这个连接器才能访问 TDengine 数据库中的数据。

简单来说:它是 Java 应用程序和 TDengine 数据库之间的"桥梁"。

连接器的两种类型

TDengine 提供了两种连接方式,就像去一个地方可以选择不同的交通工具:

  1. 原生连接(Native Connection)

    • 速度快,性能好
    • 需要在本地安装 TDengine 客户端驱动
    • 适合:服务器端应用、性能要求高的场景
  2. 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

原因:使用原生连接但未安装客户端驱动

解决方案

  1. 安装 TDengine 客户端
  2. 或改用 WebSocket 连接(推荐)

问题 3:批量插入性能不佳

原因 :使用了 addBatch() + executeBatch() 方式

优化方案

  1. 在一条 INSERT 语句中拼接多个 VALUES
  2. 使用 PreparedStatement 参数绑定
  3. 使用多线程并发插入

问题 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 提供实时分析、可视化、事件管理与报警等功能。

相关推荐
Evand J14 小时前
MATLAB例程【二维,UKF,速度滤波】DVL与IMU的融合例程,模拟速度和惯导的融合,适用于二维平面、非线性的运动轨迹
开发语言·matlab·滤波·定位
骑着蜗牛闯宇宙14 小时前
TP8上传Excel地址数据批量标注到高德地图
数据库·php·excel
weixin_5316518114 小时前
File.stream() 与 FormData 技术详解
开发语言·前端·javascript
yaoxin52112314 小时前
282. Java Stream API - 从 Collection 或 Iterator 创建 Stream
java
Allen_LVyingbo14 小时前
医疗AI多智能体协同路径规划(Cooperative Multi-Agent Path Finding)技术综述(上)
人工智能·python·算法·知识图谱·健康医疗
V搜xhliang024614 小时前
大数据与人工智能背景下的影像组学:肾脏肿瘤精准诊疗新范式
大数据·人工智能
indexsunny14 小时前
互联网大厂Java面试实战:Spring Boot、微服务与Kafka在电商场景中的应用
java·spring boot·redis·junit·kafka·mockito·microservices
彩色面团儿14 小时前
Pycharm部署pytest运行测试(测试笔记一)
python·pycharm·集成测试·pytest
悟能不能悟14 小时前
openfeign 返回void和ResponseEntity的区别
java