Le SDK LindormTSDB propose trois catégories d'interfaces : des interfaces de gestion pour les opérations DDL (Data Definition Language) et DCL (Data Control Language), des interfaces d'écriture pour l'ingestion d'enregistrements de séries temporelles, ainsi qu'une interface de requête permettant de récupérer des données via SQL.
Interfaces de gestion
Les interfaces de gestion exécutent des instructions SQL sur LindormTSDB. Deux méthodes surchargées sont disponibles :
| Signature de la méthode | Description |
|---|---|
Result execute(String sql) |
Exécute une instruction SQL sur la base de données par défaut |
Result execute(String database, String sql) |
Exécute une instruction SQL sur la base de données spécifiée |
L'objet Result contient le résultat de l'exécution :
| Champ | Type | Description |
|---|---|---|
columns |
List<String> |
Noms des colonnes dans les résultats renvoyés |
metadata |
List<String> |
Types de données des colonnes |
rows |
List<List<Object>> |
Résultats renvoyés ligne par ligne |
Gérer les bases de données et les tables
Utilisez des instructions DDL pour créer, décrire et supprimer des bases de données ou des tables. L'exemple suivant illustre un cycle de vie complet de création et de suppression :
// 1. List existing databases.
String showDatabase = "show databases";
Result result = lindormTSDBClient.execute(showDatabase);
System.out.println("before create, db list: " +
result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));
// 2. Create a database named "demo".
String createDatabase = "create database demo";
result = lindormTSDBClient.execute(createDatabase);
System.out.println("create database:" + result.isSuccessful());
// 3. Verify the database was created.
result = lindormTSDBClient.execute(showDatabase);
System.out.println("after create, db list: " +
result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));
String database = "demo";
// 4. List existing tables in the database.
String showTables = "show tables";
result = lindormTSDBClient.execute(database, showTables);
System.out.println("before create, table list: " +
result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));
// 5. Create a table.
String createTable = "CREATE TABLE sensor (device_id VARCHAR TAG, region VARCHAR TAG, " +
"time BIGINT, temperature DOUBLE, humidity DOUBLE, PRIMARY KEY(device_id))";
result = lindormTSDBClient.execute(database, createTable);
System.out.println("create table: " + result.isSuccessful());
// 6. Verify the table was created.
result = lindormTSDBClient.execute(database, showTables);
System.out.println("after create, table list: " +
result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));
// 7. Describe the table schema.
String describeTable = "describe table sensor";
result = lindormTSDBClient.execute(database, describeTable);
System.out.println("------------ describe table -------------------");
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("column #" + i + " : " + row);
}
System.out.println("------------ describe table -------------------");
// 8. Drop the table.
String dropTable = "drop table sensor";
result = lindormTSDBClient.execute(database, dropTable);
System.out.println("drop table: " + result.isSuccessful());
// 9. Verify the table was dropped.
result = lindormTSDBClient.execute(database, showTables);
System.out.println("after drop, table list: " +
result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));
// 10. Drop the database.
String dropDatabase = "drop database demo";
result = lindormTSDBClient.execute(dropDatabase);
System.out.println("drop database:" + result.isSuccessful());
// 11. Verify the database was dropped.
result = lindormTSDBClient.execute(showDatabase);
System.out.println("after drop, db list : " +
result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));
Résultat attendu :
before create, db list: [default]
create database:true
after create, db list: [default, demo]
before create, table list: []
create table: true
after create, table list: [sensor]
------------ describe table -------------------
columns: [columnName, typeName, columnKind]
metadata: [VARCHAR, VARCHAR, VARCHAR]
column #0 : [device_id, VARCHAR, TAG]
column #1 : [region, VARCHAR, TAG]
column #2 : [time, TIMESTAMP, TIMESTAMP]
column #3 : [temperature, DOUBLE, FIELD]
column #4 : [humidity, DOUBLE, FIELD]
------------ describe table -------------------
drop table: true
after drop, table list: []
drop database:true
after drop, db list : [default]
Les opérations DDL relatives aux requêtes continues ne sont pas abordées ici. Pour connaître la syntaxe SQL complète prise en charge par LindormTSDB, consultez la rubrique Syntaxe SQL.
Interfaces d'écriture
Par défaut, le SDK LindormTSDB écrit les données de manière asynchrone afin de maximiser le débit. Les interfaces d'écriture prennent en charge :
Les écritures unitaires et par lot (les écritures par lot réduisent la contention des verrous dans la file d'attente asynchrone et sont recommandées)
Deux modèles de gestion des résultats :
CompletableFuture<WriteResult>pour un traitement en ligne etCallbackpour une gestion pilotée par les événementsLes écritures synchrones en appelant
.join()sur l'objetCompletableFuturerenvoyé
Construire un enregistrement à écrire
Un objet Record contient une seule ligne à écrire. Spécifiez le nom de la table, l'horodatage, les tags et les valeurs des champs :
Record record = Record
.table("sensor") // Table name
.time(currentTime) // Timestamp in milliseconds
.tag("device_id", "F07A1260") // Tag: indexed key-value dimension
.tag("region", "north-cn")
.addField("temperature", 12.1) // Field: non-indexed metric value
.addField("humidity", 45.0)
.build();
Par défaut, le SDK valide la validité des caractères lors de la construction d'un Record. Transmettez false à la méthode build() pour ignorer cette validation.
Écrire avec CompletableFuture
Toutes les surcharges renvoient un objet CompletableFuture<WriteResult>. Privilégiez les écritures par lot pour réduire la contention des verrous dans la file d'attente asynchrone.
| Signature de la méthode | Description |
|---|---|
CompletableFuture<WriteResult> write(Record record) |
Écrit un seul enregistrement dans la base de données par défaut |
CompletableFuture<WriteResult> write(String database, Record record) |
Écrit un seul enregistrement dans la base de données spécifiée |
CompletableFuture<WriteResult> write(List<Record> records) |
Écrit un lot d'enregistrements dans la base de données par défaut (recommandé) |
CompletableFuture<WriteResult> write(String database, List<Record> records) |
Écrit un lot d'enregistrements dans la base de données spécifiée (recommandé) |
Enregistrement unique :
// Default database
CompletableFuture<WriteResult> future = lindormTSDBClient.write(record);
// Specified database
String database = "demo";
CompletableFuture<WriteResult> future = lindormTSDBClient.write(database, record);
Écriture par lot (recommandée) :
List<Record> records;
// Default database
CompletableFuture<WriteResult> future = lindormTSDBClient.write(records);
// Specified database
String database = "demo";
CompletableFuture<WriteResult> future = lindormTSDBClient.write(database, records);
Gérer le résultat :
CompletableFuture<WriteResult> future = lindormTSDBClient.write(records);
future.whenComplete((r, ex) -> {
if (ex != null) {
// Write submission failed.
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 {
// Write completed.
if (r.isSuccessful()) {
System.out.println("Write successfully.");
} else {
System.out.println("Write failure.");
}
}
});
N'effectuez pas de calculs complexes ou chronophages au sein de la méthode whenComplete. Déléguez ce type de traitement à un pool de threads indépendant. Pour plus de détails sur les codes d'erreur, consultez la rubrique Codes d'erreur courants.
Écrire avec un callback
Transmettez un Callback à la méthode write(). La méthode onCompletion reçoit le résultat de l'écriture, les enregistrements correspondants ainsi que toute exception éventuelle.
public interface Callback {
void onCompletion(WriteResult result, List<Record> records, Throwable e);
}
| Signature de la méthode | Description |
|---|---|
write(Record record, Callback callback) |
Écrit un seul enregistrement dans la base de données par défaut avec un callback |
write(String database, Record record, Callback callback) |
Écrit un seul enregistrement dans la base de données spécifiée avec un callback |
write(List<Record> records, Callback callback) |
Écrit un lot d'enregistrements dans la base de données par défaut avec un callback (recommandé) |
write(String database, List<Record> records, Callback callback) |
Écrit un lot d'enregistrements dans la base de données spécifiée avec un callback (recommandé) |
Implémenter et transmettre le callback :
Callback callback = new Callback() {
@Override
public void onCompletion(WriteResult result, List<Record> list, Throwable throwable) {
if (throwable != null) {
// Write failed.
if (throwable instanceof LindormTSDBException) {
LindormTSDBException ex = (LindormTSDBException) throwable;
System.out.println("errorCode: " + ex.getCode());
System.out.println("sqlstate: " + ex.getSqlstate());
System.out.println("message: " + ex.getMessage());
} else {
throwable.printStackTrace();
}
} else {
if (result.isSuccessful()) {
System.out.println("Write successfully.");
} else {
System.out.println("Write failure.");
}
}
}
};
// Batch write — recommended
List<Record> records;
lindormTSDBClient.write(records, callback);
// Single record
lindormTSDBClient.write(record, callback);
Évitez d'effectuer des calculs complexes ou longs au sein de la méthode onCompletion. Confiez ces tâches à un pool de threads dédié. Pour plus d'informations sur les codes d'erreur, reportez-vous à la section Codes d'erreur courants.
Interface de requête
L'interface de requête exécute des instructions SQL et renvoie les résultats par blocs. Toutes les surcharges retournent un objet ResultSet.
| Signature de la méthode | Description |
|---|---|
ResultSet query(String sql) |
Interroge la base de données par défaut ; renvoie jusqu'à 1 000 lignes par bloc |
ResultSet query(String database, String sql) |
Interroge la base de données spécifiée ; renvoie jusqu'à 1 000 lignes par bloc |
ResultSet query(String database, String sql, int chunkSize) |
Interroge la base de données spécifiée avec une taille de bloc personnalisée |
Paramètres :
| Paramètre | Type | Description |
|---|---|---|
database |
String |
Nom de la base de données à interroger |
sql |
String |
Instruction SQL à exécuter. Pour la syntaxe prise en charge, consultez la page Syntaxe SQL. |
chunkSize |
int |
Nombre de lignes renvoyées par lot. Valeur par défaut : 1 000. |
Traiter les résultats de requête
Parcourez l'objet ResultSet à l'aide de la méthode next() jusqu'à ce qu'elle renvoie null, puis fermez le jeu de résultats pour libérer les ressources d'E/S :
public interface ResultSet extends Closeable {
QueryResult next();
void close();
}
Chaque objet QueryResult contient :
| Champ | Type | Description |
|---|---|---|
columns |
List<String> |
Noms des colonnes dans les résultats de la requête |
metadata |
List<String> |
Types de données des colonnes. Consultez la section Types de données. |
rows |
List<List<Object>> |
Résultats de la requête renvoyés ligne par ligne |
Exemple :
String sql = "select * from sensor";
int chunkSize = 100;
ResultSet resultSet = lindormTSDBClient.query("demo", sql, chunkSize);
try {
QueryResult result = null;
// Iterate until next() returns null — all results have been retrieved.
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 ResultSet after the query — whether it succeeds or fails.
resultSet.close();
}
Appelez systématiquement resultSet.close() une fois la requête terminée, qu'elle ait réussi ou échoué. Omettre cette étape entraîne une fuite de connexion.