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

相关推荐
鱼跃鹰飞1 天前
设计模式系列:工厂模式
java·设计模式·系统架构
好好学习啊天天向上1 天前
C盘容量不够,python , pip,安装包的位置
linux·python·pip
时见先生1 天前
Python库和conda搭建虚拟环境
开发语言·人工智能·python·自然语言处理·conda
二十雨辰1 天前
[python]-循环语句
服务器·python
a努力。1 天前
国家电网Java面试被问:混沌工程在分布式系统中的应用
java·开发语言·数据库·git·mysql·面试·职场和发展
Yvonne爱编码1 天前
Java 四大内部类全解析:从设计本质到实战应用
java·开发语言·python
wqwqweee1 天前
Flutter for OpenHarmony 看书管理记录App实战:搜索功能实现
开发语言·javascript·python·flutter·harmonyos
li_wen011 天前
文件系统(八):Linux JFFS2文件系统工作原理、优势与局限
大数据·linux·数据库·文件系统·jffs2
J2虾虾1 天前
SpringBoot和mybatis Plus不兼容报错的问题
java·spring boot·mybatis
yongui478341 天前
基于MATLAB的NALM锁模光纤激光器仿真实现
开发语言·matlab