教程:通过Druid连接池连接并访问时序引擎

本文介绍通过Druid连接池连接并访问时序引擎的方法。

背景信息

使用Java开发访问时序引擎的应用程序时,通常建议通过JDBC Driver连接Lindorm时序引擎。JDBC访问逻辑的基础是需要创建Connection对象,如果每次连接时序引擎都创建一个新的Connection对象,会带来很大的开销。为了降低开销,可以使用连接池来执行连接的创建和管理。

前提条件

  • 已安装Java环境,要求安装JDK 1.8及以上版本。

  • 已将客户端IP地址添加至Lindorm白名单,具体操作,请参见设置白名单

操作步骤

以开源连接池Alibaba Druid为例。

  1. 配置连接池Druid的参数。在Maven项目的src/main/resources目录中新建druid.properties文件,并在文件中添加以下内容。

    # 驱动类名,无需替换
    driverClassName=com.aliyun.lindorm.table.client.Driver
    # url、username、password需要替换为业务实际的内容,可以在Lindorm控制台上获取
    url=jdbc:lindorm:tsdb:url=http://ld-bp12pt80qr38p****-proxy-tsdb-pub.lindorm.rds.aliyuncs.com:8242
    username=root
    password=root
    # 连接属性,指定要连接的database,需根据实际情况将****替换为实际的内容
    connectionProperties=database=default
    
    # 初始化连接池即创建连接,建议保持不变
    init=true
    # 初始化连接池时建立连接的个数,可以根据实际情况调整
    initialSize=10
    # 连接池中允许的最小空闲连接数量,可以根据实际情况调整
    minIdle=10
    # 连接池中允许的最大连接数量,可以根据实际情况调整
    maxActive=20
    # 获取连接最大等待时间,单位毫秒,建议保持不变
    maxWait=30000
    
    # 连接保活配置项,建议保持不变,否则可能出现连接断开
    # 异常ConnectionDisconnectedException
    druid.keepAlive=true
    druid.keepAliveBetweenTimeMillis=30000
    minEvictableIdleTimeMillis=600000
    maxEvictableIdleTimeMillis=900000
    timeBetweenEvictionRunsMillis=5000
    
    # 连接验证配置项,建议保持不变
    validationQuery=SELECT 1
    testWhileIdle=true
    testOnBorrow=false
    testOnReturn=false
    
    # PreparedStatement缓存配置项,这里配置为关闭缓存,建议保持不变
    # 否则运行时可能会出现NoSuchStatement异常
    poolPreparedStatements=false
    maxOpenPreparedStatements=-1
    druid.maxPoolPreparedStatementPerConnectionSize=-1
    说明
    • url为时序引擎的JDBC连接地址,相关参数说明,请参见JDBC连接地址说明

    • 默认用户名及密码均为root

  2. 在Maven项目中添加Druid连接池的依赖。打开客户端,创建Project并在pom.xml中配置Maven依赖。示例代码如下:

    <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
          <version>1.2.6</version>
        </dependency>
  3. 通过以下两种方式安装Lindorm JDBC Driver依赖。

    • 手动安装。

      在本地自行下载JAR包集成JDBC Driver,下载链接为:Lindorm-all-client。选择需要安装的版本,以2.1.5为例,下载lindorm-all-client-2.1.5.jar包。

    • 通过Maven下载。

      如果在Maven项目中集成JDBC Driver,创建Project并在pom.xml中添加以下依赖配置,具体内容如下:

      <dependency>
          <groupId>com.aliyun.lindorm</groupId>  
          <artifactId>lindorm-all-client</artifactId>
          <version>2.2.1.3</version>
      </dependency>
      说明

      lindorm-all-client的版本号根据需求填写。

  4. 加载连接池Druid的参数并初始化连接池Druid。

    // 加载参数
    Properties properties = new Properties();
    InputStream inputStream = tsdb.class.getClassLoader().getResourceAsStream("druid.properties");
    properties.load(inputStream);
    // 初始化连接池
    DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
  5. 通过连接池Druid获取JDBC的连接信息并访问Lindorm时序引擎。

    // 创建表
    try (Connection connection = dataSource.getConnection()) {
      try (Statement statement = connection.createStatement()) {
          String sql = "CREATE TABLE sensor (device_id VARCHAR TAG,region VARCHAR TAG,time TIMESTAMP,temperature DOUBLE,humidity DOUBLE,PRIMARY KEY(device_id))";
          int ret = statement.executeUpdate(sql);
          System.out.println(ret);
       }
    }
    // 插入数据
    try (Connection connection = dataSource.getConnection()) {
      try (Statement stmt = connection.createStatement()) {
         stmt.addBatch("INSERT INTO sensor(device_id, region, time, temperature, humidity) values('F07A1260','north-cn','2021-04-22 15:33:00',12.1,45)");
         stmt.addBatch("INSERT INTO sensor(device_id, region, time, temperature, humidity) values('F07A1260','north-cn','2021-04-22 15:33:10',13.2,47)");
         stmt.addBatch("INSERT INTO sensor(device_id, region, time, temperature, humidity) values('F07A1260','north-cn','2021-04-22 15:33:20',10.6,46)");
         stmt.addBatch("INSERT INTO sensor(device_id, region, time, temperature, humidity) values('F07A1261','south-cn','2021-04-22 15:33:00',18.1,44)");
         stmt.addBatch("INSERT INTO sensor(device_id, region, time, temperature, humidity) values('F07A1261','south-cn','2021-04-22 15:33:10',19.7,44)");
         stmt.executeBatch();
      }
    }
    // 查询数据
    // 使用绑定参数的方式查询数据
    // 强烈建议指定时间范围减少数据扫描
    try (Connection connection = dataSource.getConnection()) {
        try (PreparedStatement pstmt = connection.prepareStatement("SELECT device_id, region,time,temperature,humidity FROM sensor WHERE time >= ? and time <= ?")) {
            Timestamp startTime = Timestamp.valueOf("2021-04-22 15:33:00");
            Timestamp endTime = Timestamp.valueOf("2021-04-22 15:33:20");
            pstmt.setTimestamp(1, startTime);
            pstmt.setTimestamp(2, endTime);
    
        try (ResultSet rs = pstmt.executeQuery()) {
            while (rs.next()) {
                String device_id = rs.getString("device_id");
                String region = rs.getString("region");
                Timestamp time = rs.getTimestamp("time");
                Double temperature = rs.getDouble("temperature");
                Double humidity = rs.getDouble("humidity");
                System.out.printf("%s %s %s %f %f\n", device_id, region, time, temperature, humidity);
             }
        }
      }
    }

完整示例

单击查看完整示例

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class tsdb{
    public static void main(String[] args) throws Exception {
        // 加载参数
        Properties properties = new Properties();
        InputStream inputStream = tsdb.class.getClassLoader().getResourceAsStream("druid.properties");
        properties.load(inputStream);
        // 初始化连接池
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);


        // 创建表
        try (Connection connection = dataSource.getConnection()) {
            try (Statement statement = connection.createStatement()) {
                String sql = "CREATE TABLE sensor (device_id VARCHAR TAG,region VARCHAR TAG,time TIMESTAMP,temperature DOUBLE,humidity DOUBLE,PRIMARY KEY(device_id))";
                int ret = statement.executeUpdate(sql);
                System.out.println(ret);
            }
        }

        // 插入数据
        try (Connection connection = dataSource.getConnection()) {
            try (Statement stmt = connection.createStatement()) {
                stmt.addBatch("INSERT INTO sensor(device_id, region, time, temperature, humidity) values('F07A1260','north-cn','2021-04-22 15:33:00',12.1,45)");
                stmt.addBatch("INSERT INTO sensor(device_id, region, time, temperature, humidity) values('F07A1260','north-cn','2021-04-22 15:33:10',13.2,47)");
                stmt.addBatch("INSERT INTO sensor(device_id, region, time, temperature, humidity) values('F07A1260','north-cn','2021-04-22 15:33:20',10.6,46)");
                stmt.addBatch("INSERT INTO sensor(device_id, region, time, temperature, humidity) values('F07A1261','south-cn','2021-04-22 15:33:00',18.1,44)");
                stmt.addBatch("INSERT INTO sensor(device_id, region, time, temperature, humidity) values('F07A1261','south-cn','2021-04-22 15:33:10',19.7,44)");
                stmt.executeBatch();
            }
        }

        // 查询数据
        // 使用绑定参数的方式查询数据
        // 强烈建议指定时间范围减少数据扫描
        try (Connection connection = dataSource.getConnection()) {
            try (PreparedStatement pstmt = connection.prepareStatement("SELECT device_id, region,time,temperature,humidity FROM sensor WHERE time >= ? and time <= ?")) {
                Timestamp startTime = Timestamp.valueOf("2021-04-22 15:33:00");
                Timestamp endTime = Timestamp.valueOf("2021-04-22 15:33:20");
                pstmt.setTimestamp(1, startTime);
                pstmt.setTimestamp(2, endTime);


                //pstmt.setString(1, "2021-04-22 15:33:00");
               // pstmt.setString(2, "2021-04-22 15:33:20");
                try (ResultSet rs = pstmt.executeQuery()) {
                    while (rs.next()) {
                        String device_id = rs.getString("device_id");
                        String region = rs.getString("region");
                        Timestamp time = rs.getTimestamp("time");
                        Double temperature = rs.getDouble("temperature");
                        Double humidity = rs.getDouble("humidity");
                        System.out.printf("%s %s %s %f %f\n", device_id, region, time, temperature, humidity);
                    }
                }
            }
        }
    }
}

执行成功预计返回以下结果:

0
F07A1260 north-cn 2021-04-22 15:33:00.0 12.100000 45.000000
F07A1260 north-cn 2021-04-22 15:33:10.0 13.200000 47.000000
F07A1260 north-cn 2021-04-22 15:33:20.0 10.600000 46.000000
F07A1261 south-cn 2021-04-22 15:33:00.0 18.100000 44.000000
F07A1261 south-cn 2021-04-22 15:33:10.0 19.700000 44.000000