Use the LindormTSDB SDK for Java to connect to LindormTSDB and run your first write and query operations.
Prerequisites
Before you begin, ensure that you have:
JDK 1.8 or later installed
LindormTSDB 3.4.7 or later (see the Version guide for LindormTSDB to check your current version, and Minor version update to upgrade if needed)
Your client IP address added to the Lindorm whitelist
Install the SDK
Three installation methods are available. Maven is recommended for most projects.
Method 1: Maven (recommended)
Add the following dependency to the dependencies section of your pom.xml:
<dependency>
<groupId>com.aliyun.lindorm</groupId>
<artifactId>lindorm-tsdb-client</artifactId>
<version>1.0.4</version>
</dependency>A sample Maven project is available for download. Get the sample project to compile and run it locally, or use it as a starting point for your own project.
All SDK versions are available in the Maven central repository. For version details, see the SDK version guide.
Method 2: JAR package in Eclipse
Download the Java SDK package and decompress it.
In Eclipse, right-click your project and select Properties.
Click , select
lindorm-tsdb-client-1.0.0.jarand all JAR packages in thelibdirectory, then click Apply and Close.
Method 3: JAR package in IntelliJ IDEA
Download the Java SDK package and decompress it.
In IntelliJ IDEA, click .
In the left navigation pane, select .
Click
and select JARs or directories.Select
lindorm-tsdb-client-1.0.0.jarand all JAR packages in thelibdirectory, then click OK.Click Apply, then OK.
Connect to LindormTSDB
Create a LindormTSDBClient by passing your time series engine endpoint to ClientOptions. The client is thread-safe — create one instance and reuse it throughout your application.
String url = "http://ld-bp17j28j2y7pm****-proxy-tsdb-pub.lindorm.rds.aliyuncs.com:8242";
// LindormTSDBClient is thread-safe. Create it once and reuse it.
ClientOptions options = ClientOptions.newBuilder(url).build();
LindormTSDBClient lindormTSDBClient = LindormTSDBFactory.connect(options);Replace the URL with your actual time series engine endpoint.
Create a database and table
Create a database named demo and a time series table named sensor. For the full SQL syntax, see CREATE DATABASE and CREATE TABLE.
lindormTSDBClient.execute("CREATE DATABASE demo");
lindormTSDBClient.execute("demo", "CREATE TABLE sensor (" +
"device_id VARCHAR TAG, " +
"region VARCHAR TAG, " +
"time BIGINT, " +
"temperature DOUBLE, " +
"humidity DOUBLE, " +
"PRIMARY KEY(device_id))");Write data
LindormTSDBClient supports two write modes:
| Mode | Method | When to use |
|---|---|---|
| Asynchronous (default) | write() returns CompletableFuture<WriteResult> | High-throughput production workloads; the client batches writes automatically |
| Synchronous | Call future.join() on the returned future | Scripts, one-off operations, or when you need to confirm each write before proceeding |
Build a list of Record objects and call write():
int numRecords = 10;
List<Record> records = new ArrayList<>(numRecords);
long currentTime = System.currentTimeMillis();
for (int i = 0; i < numRecords; i++) {
Record record = Record
.table("sensor")
.time(currentTime + i * 1000)
.tag("device_id", "F07A1260")
.tag("region", "north-cn")
.addField("temperature", 12.1 + i)
.addField("humidity", 45.0 + i)
.build();
records.add(record);
}
// Asynchronous write — handle the result in the callback
CompletableFuture<WriteResult> future = lindormTSDBClient.write("demo", records);
future.whenComplete((r, ex) -> {
if (ex != null) {
System.out.println("Failed to write.");
Throwable throwable = ExceptionUtils.getRootCause(ex);
if (throwable instanceof LindormTSDBException) {
LindormTSDBException e = (LindormTSDBException) throwable;
System.out.println("Error Code: " + e.getCode());
System.out.println("SQL State: " + e.getSqlstate());
System.out.println("Error Message: " + e.getMessage());
} else {
throwable.printStackTrace();
}
} else {
System.out.println("Write successfully.");
}
});
// To block until the write completes, call join()
System.out.println(future.join());Query data
Run SQL queries with query(). Results are returned in batches of 1,000 rows by default. Iterate with resultSet.next() until it returns null, then close the ResultSet to release I/O resources.
String sql = "select * from sensor limit 10";
ResultSet resultSet = lindormTSDBClient.query("demo", sql);
try {
QueryResult result;
// next() returns null when all rows have been read
while ((result = resultSet.next()) != null) {
List<String> columns = result.getColumns();
System.out.println("columns: " + columns);
List<String> metadata = result.getMetadata();
System.out.println("metadata: " + metadata);
List<List<Object>> rows = result.getRows();
for (int i = 0, size = rows.size(); i < size; i++) {
System.out.println("row #" + i + " : " + rows.get(i));
}
}
} finally {
// Always close the ResultSet to release I/O resources
resultSet.close();
}For more SQL query options, see Basic queries.
Complete code example
import com.aliyun.lindorm.tsdb.client.ClientOptions;
import com.aliyun.lindorm.tsdb.client.LindormTSDBClient;
import com.aliyun.lindorm.tsdb.client.LindormTSDBFactory;
import com.aliyun.lindorm.tsdb.client.exception.LindormTSDBException;
import com.aliyun.lindorm.tsdb.client.model.QueryResult;
import com.aliyun.lindorm.tsdb.client.model.Record;
import com.aliyun.lindorm.tsdb.client.model.ResultSet;
import com.aliyun.lindorm.tsdb.client.model.WriteResult;
import com.aliyun.lindorm.tsdb.client.utils.ExceptionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public class QuickStart {
public static void main(String[] args) {
// 1. Create a client instance.
String url = "http://ld-xxxx-proxy-tsdb-pub.lindorm.rds.aliyuncs.com:8242";
// LindormTSDBClient is thread-safe. Create it once and reuse it.
ClientOptions options = ClientOptions.newBuilder(url).build();
LindormTSDBClient lindormTSDBClient = LindormTSDBFactory.connect(options);
// 2. Create a database named demo and a table named sensor.
lindormTSDBClient.execute("CREATE DATABASE demo");
lindormTSDBClient.execute("demo", "CREATE TABLE sensor (device_id VARCHAR TAG,region VARCHAR TAG,time BIGINT,temperature DOUBLE,humidity DOUBLE,PRIMARY KEY(device_id))");
// 3. Write data.
int numRecords = 10;
List<Record> records = new ArrayList<>(numRecords);
long currentTime = System.currentTimeMillis();
for (int i = 0; i < numRecords; i++) {
Record record = Record
.table("sensor")
.time(currentTime + i * 1000)
.tag("device_id", "F07A1260")
.tag("region", "north-cn")
.addField("temperature", 12.1 + i)
.addField("humidity", 45.0 + i)
.build();
records.add(record);
}
CompletableFuture<WriteResult> future = lindormTSDBClient.write("demo", records);
// Process the asynchronous write result.
future.whenComplete((r, ex) -> {
// Handle write failures.
if (ex != null) {
System.out.println("Failed to write.");
Throwable throwable = ExceptionUtils.getRootCause(ex);
if (throwable instanceof LindormTSDBException) {
LindormTSDBException e = (LindormTSDBException) throwable;
System.out.println("Caught an LindormTSDBException, which means your request made it to Lindorm TSDB, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Code: " + e.getCode());
System.out.println("SQL State: " + e.getSqlstate());
System.out.println("Error Message: " + e.getMessage());
} else {
throwable.printStackTrace();
}
} else {
System.out.println("Write successfully.");
}
});
// Block until the write completes.
System.out.println(future.join());
// 4. Query data.
String sql = "select * from sensor limit 10";
ResultSet resultSet = lindormTSDBClient.query("demo", sql);
try {
// Results are returned in batches of 1,000 rows by default.
// next() returns null when all rows have been read.
QueryResult result;
while ((result = resultSet.next()) != null) {
List<String> columns = result.getColumns();
System.out.println("columns: " + columns);
List<String> metadata = result.getMetadata();
System.out.println("metadata: " + metadata);
List<List<Object>> rows = result.getRows();
for (int i = 0, size = rows.size(); i < size; i++) {
List<Object> row = rows.get(i);
System.out.println("row #" + i + " : " + row);
}
}
} finally {
// Always close the ResultSet to release I/O resources.
resultSet.close();
}
// 5. Shut down the client to release resources.
lindormTSDBClient.shutdown();
}
}What's next
CREATE DATABASE — full syntax for creating databases
CREATE TABLE — full syntax for creating time series tables
Basic queries — SQL query reference for LindormTSDB
SDK version guide — release notes for the Java Native SDK