Passer au contenu principal
Bibliothèque client Java permettant de communiquer avec un serveur de base de données via ses protocoles. L’implémentation actuelle ne prend en charge que l’interface HTTP. La bibliothèque fournit sa propre API pour envoyer des requêtes à un serveur, ainsi que des outils pour travailler avec différents formats de données binaires (RowBinary* & Native*).

Configuration



Initialisation

L’objet Client est initialisé par com.clickhouse.client.api.Client.Builder#build(). Chaque client possède son propre contexte et aucun objet n’est partagé entre eux. Le Builder dispose de méthodes de configuration pour en simplifier la mise en œuvre.Exemple :
showLineNumbers
Client est AutoCloseable et doit être fermé lorsqu’il n’est plus nécessaire.

Authentification

L’authentification est configurée par client lors de la phase d’initialisation. Trois méthodes d’authentification sont prises en charge : par mot de passe, par jeton d’accès ou par certificat client SSL.L’authentification par mot de passe nécessite de renseigner le nom d’utilisateur et le mot de passe en appelant setUsername(String) et setPassword(String) :
showLineNumbers
L’authentification par jeton d’accès nécessite de configurer le jeton d’accès en appelant setAccessToken(String) :
showLineNumbers
L’authentification par certificat client SSL nécessite de définir le nom d’utilisateur, d’activer l’authentification SSL, de configurer un certificat client et une clé client en appelant respectivement setUsername(String), useSSLAuthentication(boolean), setClientCertificate(String) et setClientKey(String) :
showLineNumbers
L’authentification SSL peut être difficile à dépanner en production, car de nombreuses erreurs provenant des bibliothèques SSL ne fournissent pas assez d’informations. Par exemple, si le certificat client et la clé ne correspondent pas, le serveur interrompra immédiatement la connexion (dans le cas de HTTP, cela se produira à l’étape d’établissement de la connexion, lorsqu’aucune requête HTTP n’est envoyée, donc aucune réponse n’est renvoyée).Veuillez utiliser des outils comme openssl pour vérifier les certificats et les clés :
  • vérifier l’intégrité de la clé : openssl rsa -in [key-file.key] -check -noout
  • vérifier que le certificat client a un CN correspondant pour un utilisateur :
    • obtenir le CN à partir d’un certificat utilisateur - openssl x509 -noout -subject -in [user.cert]
    • vérifier que la même valeur est définie dans la base de données select name, auth_type, auth_params from system.users where auth_type = 'ssl_certificate' (la requête affichera auth_params avec quelque chose comme {"common_names":["some_user"]})

Configuration

Tous les paramètres sont définis par des méthodes d’instance (aussi appelées méthodes de configuration) qui rendent explicites la portée et le contexte de chaque valeur. Les principaux paramètres de configuration sont définis dans une seule portée (client ou opération) et ne se substituent pas mutuellement.La configuration est définie lors de la création du client. Voir com.clickhouse.client.api.Client.Builder.

Configuration du client


Identification du client

Le journal de requêtes contient deux champs permettant d’identifier l’application à l’origine d’une requête : client_name et http_user_agent. Le protocole TCP natif utilise client_name pour identifier l’application. Le protocole HTTP utilise http_user_agent pour identifier l’application. Le builder client dispose de la méthode setClientName pour définir les valeurs correctes pour les deux protocoles. Le champ http_user_agent est défini selon le format standard de l’en-tête User-Agent : application-name[/version] [(operating-system; architecture; ...)]. Cet ensemble de valeurs est répété pour chaque couche : application, bibliothèque client, bibliothèque client HTTP. Ce qui est défini par la méthode setClientName apparaît en premier dans la liste.Par exemple :
showLineNumbers
donnera la valeur http_user_agent suivante :
L’application peut définir son propre en-tête HTTP User-Agent pour s’identifier. Toutefois, la partie clickhouse-java-v2/0.9.6-SNAPSHOT sera ajoutée à la fin de l’en-tête.

Identification des opérations

Le journal de requêtes dispose de deux autres champs query_id et log_comment qui peuvent être utilisés pour identifier une opération et ajouter des informations supplémentaires au journal de requêtes.query_id est un identifiant unique d’une opération. Il peut être défini par l’application en appelant la méthode setQueryId de la classe QuerySettings.
showLineNumbers
log_comment est un commentaire pouvant être ajouté au journal des requêtes. Il peut être défini par l’application en appelant la méthode logComment de la classe QuerySettings.
showLineNumbers

Paramètres du serveur

Les paramètres côté serveur peuvent être définis au niveau du client une seule fois lors de sa création (voir la méthode serverSetting du Builder) et au niveau de l’opération (voir serverSetting pour la classe de paramètres d’opération).
showLineNumbers
⚠️ Lorsque des options sont définies via la méthode setOption (que ce soit via Client.Builder ou la classe de paramètres d’opération), le nom des paramètres serveur doit être préfixé de clickhouse_setting_. La méthode com.clickhouse.client.api.ClientConfigProperties#serverSetting() peut s’avérer utile dans ce cas.

En-tête HTTP personnalisé

Des en-têtes HTTP personnalisés peuvent être définis pour toutes les opérations (au niveau du client) ou pour une seule (au niveau de l’opération).
showLineNumbers
Lorsque les options sont définies via la méthode setOption (que ce soit via Client.Builder ou la classe de paramètres d’opération), le nom du header personnalisé doit être préfixé de http_header_. La méthode com.clickhouse.client.api.ClientConfigProperties#httpHeader() peut s’avérer utile dans ce cas.

Définitions courantes

ClickHouseFormat

Enum des formats pris en charge. Il inclut tous les formats supportés par ClickHouse.
  • raw - l’utilisateur doit transcoder les données brutes
  • full - le client peut transcoder lui-même les données et accepte un flux de données brutes
  • - - opération non prise en charge par ClickHouse pour ce format
Cette version du client prend en charge :

API d’insertion

insert(String tableName, InputStream data, ClickHouseFormat format)

Accepte des données sous forme d’InputStream d’octets dans le format spécifié. data doit être encodé dans le format.Signatures
ParamètrestableName - un nom de table cible.data - un flux d’entrée de données encodées.format - le format dans lequel les données sont encodées.settings - paramètres de la requête.Valeur de retourFuture du type InsertResponse — résultat de l’opération et informations supplémentaires telles que les métriques côté serveur.Exemples
showLineNumbers

insert(String tableName, List<?> data, InsertSettings settings)

Envoie une requête d’écriture vers la base de données. La liste des objets est convertie dans un format efficace, puis envoyée au serveur. La classe des éléments de la liste doit être enregistrée au préalable à l’aide de la méthode register(Class, TableSchema).Signatures
ParamètrestableName - nom de la table cible.data - objets DTO (Data Transfer Object) de la collection.settings - paramètres de la requête.Valeur de retourFuture du type InsertResponse — le résultat de l’opération et des informations supplémentaires telles que les métriques côté serveur.Exemples
showLineNumbers

InsertSettings

Options de configuration pour les opérations d’insertion.Méthodes de configuration

InsertResponse

Objet de réponse contenant le résultat de l’opération d’insertion. Il n’est disponible que si le client a reçu une réponse du serveur.
Cet objet doit être fermé dès que possible pour libérer la connexion, car celle-ci ne peut pas être réutilisée tant que toutes les données de la réponse précédente n’ont pas été entièrement lues.

API de requête

query(String sqlQuery)

Envoie sqlQuery tel quel. Le format de réponse est défini par les paramètres de la requête. QueryResponse contiendra une référence au flux de réponse qui doit être consommé par un lecteur pour le format pris en charge.Signatures
ParamètressqlQuery - une instruction SQL unique. La requête est envoyée telle quelle au serveur.settings - paramètres de la requête.Valeur de retourFuture du type QueryResponse — un jeu de données résultant ainsi que des informations supplémentaires telles que les métriques côté serveur. L’objet Response doit être fermé après consommation du jeu de données.Exemples

query(String sqlQuery, Map<String, Object> queryParams, QuerySettings settings)

Envoie sqlQuery tel quel. Envoie également les paramètres de requête afin que le serveur puisse compiler l’expression SQL.Signatures
ParamètressqlQuery - expression SQL avec des espaces réservés {}.queryParams - map de variables permettant de compléter l’expression SQL sur le serveur.settings - paramètres de la requête.Valeur de retourFuture du type QueryResponse — un jeu de données résultant ainsi que des informations supplémentaires telles que les métriques côté serveur. L’objet Response doit être fermé après consommation du jeu de données.Exemples
showLineNumbers

queryAll(String sqlQuery)

Interroge des données au format RowBinaryWithNamesAndTypes. Renvoie le résultat sous forme de collection. Les performances de lecture sont identiques à celles du lecteur, mais davantage de mémoire est nécessaire pour conserver l’intégralité du jeu de données.Signatures
ParamètressqlQuery - expression SQL pour interroger des données depuis un serveur.Valeur de retourJeu de données complet représenté par une liste d’objets GenericRecord offrant un accès ligne par ligne aux données de résultat.Exemples
showLineNumbers

QuerySettings

Options de configuration pour les opérations de requête.Méthodes de configuration

QueryResponse

Objet de réponse contenant le résultat de l’exécution de la requête. Il n’est disponible que si le client a reçu une réponse du serveur.
Cet objet doit être fermé dès que possible afin de libérer la connexion, car celle-ci ne peut pas être réutilisée tant que toutes les données de la réponse précédente n’ont pas été lues intégralement.

Exemples

API commune

getTableSchema(String table)

Récupère le schéma de la table table.Signatures
Paramètrestable - nom de la table pour laquelle les données de schéma doivent être récupérées.database - base de données dans laquelle la table cible est définie.Valeur de retourRenvoie un objet TableSchema contenant la liste des colonnes de la table.

getTableSchemaFromQuery(String sql)

Récupère le schéma à partir d’une instruction SQL.Signatures
Paramètressql - Instruction SQL “SELECT” dont le schéma doit être renvoyé.Valeur de retourRenvoie un objet TableSchema dont les colonnes correspondent à l’expression sql.

TableSchema

register(Class<?> clazz, TableSchema schema)

Compile la couche de sérialisation et de désérialisation pour la classe Java à utiliser pour l’écriture et la lecture de données avec schema. La méthode crée un sérialiseur et un désérialiseur pour la paire getter/setter et la colonne correspondante. La correspondance de colonne est déterminée en extrayant son nom à partir du nom de la méthode. Par exemple, getFirstName correspondra à la colonne first_name ou firstname.Signatures
Paramètresclazz - Classe représentant le POJO utilisé pour lire/écrire des données.schema - Schéma de données à utiliser pour la mise en correspondance avec les propriétés POJO.Exemples
showLineNumbers

Exemples d’utilisation

Le code des exemples complets est stocké dans un dossier ‘example` du dépôt :
  • client-v2 - principal ensemble d’exemples.
  • demo-service - exemple d’utilisation du client dans une application Spring Boot.
  • demo-kotlin-service - exemple d’utilisation du client dans une application Ktor (Kotlin).

Lecture des données

Il existe deux façons courantes de lire les données :
  • Méthode query() qui renvoie un objet QueryResponse de bas niveau contenant un InputStream avec les données. Généralement combinée à ClickHouseBinaryFormatReader pour les lectures en streaming, elle peut aussi être utilisée avec toute autre implémentation personnalisée de lecteur. QueryResponse donne également accès aux métadonnées du jeu de résultats et aux métriques.
  • Méthode queryAll() avec utilisation de GenericRecord pour un accès pratique aux lignes. Dans ce cas, l’intégralité du jeu de résultats est chargée en mémoire.
  • Méthode queryRecords() qui renvoie com.clickhouse.client.api.query.Records - un itérateur pour les objets GenericRecord. Cette méthode repose sur une approche en streaming (aucune donnée n’est chargée en mémoire) et utilise GenericRecord pour accéder aux données.
Note : l’approche en streaming nécessite une lecture rapide, faute de quoi elle peut provoquer un timeout d’écriture sur le serveur, car les données sont lues directement depuis le flux réseau.

Lecture des Arrays

Méthodes de ClickHouseBinaryFormatReader
  • getList(...) - lit n’importe quel Array(...) comme List<T>. Bon choix par défaut pour une lecture typée flexible. Prend en charge les tableaux imbriqués.
  • getByteArray(...), getShortArray(...), getIntArray(...), getLongArray(...), getFloatArray(...), getDoubleArray(...), getBooleanArray(...) - idéal pour les tableaux 1D de valeurs compatibles avec les types primitifs.
  • getStringArray(...) - pour Array(String) (et les valeurs d’enum représentées par leur nom).
  • getObjectArray(...) - option générique pour tout type d’élément de Array(...), y compris les tableaux imbriqués. À utiliser pour lire des tableaux contenant des valeurs Nullable et des tableaux imbriqués.
Des surcharges par index et par nom sont disponibles pour toutes les méthodes. L’index est basé sur 1. Les surcharges par index accèdent directement à une colonne. Les méthodes par nom nécessitent une recherche par index à chaque appel.
Méthodes de GenericRecord
  • getList(...) - lit n’importe quel Array(...) en tant que List<T>. Bon choix par défaut pour une lecture à typage flexible. Prend en charge les tableaux imbriqués.
  • getByteArray(...), getShortArray(...), getIntArray(...), getLongArray(...), getFloatArray(...), getDoubleArray(...), getBooleanArray(...) - idéal pour les tableaux 1D de valeurs compatibles avec les types primitifs.
  • getStringArray(...) - pour Array(String) (et les valeurs d’enum représentées par leur nom).
  • getObjectArray(...) - option générique pour tout type d’élément de Array(...), y compris les tableaux imbriqués. À utiliser pour lire des tableaux contenant des valeurs NULL et des tableaux imbriqués.
Des surcharges par index et par nom sont disponibles pour toutes les méthodes. L’index est basé sur 1. Les surcharges par index accèdent directement à une colonne. Les méthodes par nom nécessitent une recherche par index à chaque appel.

Guide de migration

L’ancien client (V1) utilisait com.clickhouse.client.ClickHouseClient#builder comme point de départ. Le nouveau client (V2) suit un pattern similaire avec com.clickhouse.client.api.Client.Builder. Les principales différences sont :
  • aucun service loader n’est utilisé pour charger l’implémentation. Le com.clickhouse.client.api.Client sert de classe façade pour toutes sortes d’implémentations à l’avenir.
  • moins de sources de configuration : l’une est fournie au builder et l’autre via les paramètres d’opération (QuerySettings, InsertSettings). La version précédente avait une configuration par nœud et chargeait les variables d’environnement dans certains cas.

Correspondance des paramètres de configuration

Il existe 3 classes enum liées à la configuration dans V1 :
  • com.clickhouse.client.config.ClickHouseDefaults - paramètres de configuration à définir dans la plupart des cas d’utilisation, comme USER et PASSWORD.
  • com.clickhouse.client.config.ClickHouseClientOption - paramètres de configuration spécifiques au client, comme HEALTH_CHECK_INTERVAL.
  • com.clickhouse.client.http.config.ClickHouseHttpOption - paramètres de configuration spécifiques à l’interface HTTP, comme RECEIVE_QUERY_PROGRESS.
Ils ont été conçus pour regrouper les paramètres et assurer une séparation claire. Cependant, dans certains cas, cela a pu prêter à confusion (y a-t-il une différence entre com.clickhouse.client.config.ClickHouseDefaults#ASYNC et com.clickhouse.client.config.ClickHouseClientOption#ASYNC ?). Le nouveau client V2 utilise com.clickhouse.client.api.Client.Builder comme dictionnaire unique de toutes les options de configuration possibles du client. La classe com.clickhouse.client.api.ClientConfigProperties recense tous les noms de paramètres de configuration.Le tableau ci-dessous indique quelles options de l’ancienne version sont prises en charge par le nouveau client et leur nouvelle signification.Légende : ✔ = pris en charge, ✗ = supprimé

Différences générales

  • Client V2 utilise moins de classes propriétaires afin d’améliorer la portabilité. Par exemple, V2 fonctionne avec n’importe quelle implémentation de java.io.InputStream pour envoyer des données à un serveur.
  • Le paramètre async de Client V2 est off par défaut. Cela signifie qu’il n’y a pas de thread supplémentaire et que l’application garde davantage de contrôle sur le client. Ce paramètre doit être off dans la majorité des cas d’utilisation. L’activation de async crée un thread distinct pour chaque requête. Cela n’a de sens que si vous utilisez un executor contrôlé par l’application (voir com.clickhouse.client.api.Client.Builder#setSharedOperationExecutor)

Écriture des données

  • utilisez n’importe quelle implémentation de java.io.InputStream. La V1 com.clickhouse.data.ClickHouseInputStream est prise en charge, mais n’est PAS recommandée.
  • une fois la fin du flux d’entrée détectée, elle est traitée comme telle. Auparavant, il fallait fermer le flux de sortie d’une requête.
V1 Insérer des données au format TSV.
V2 Insertion de données au format TSV.
  • il n’y a qu’une seule méthode à appeler. Il n’est pas nécessaire de créer un objet de corps de requête supplémentaire.
  • le flux du corps de la requête est fermé automatiquement une fois toutes les données copiées.
  • une nouvelle API de bas niveau est disponible com.clickhouse.client.api.Client#insert(java.lang.String, java.util.List<java.lang.String>, com.clickhouse.client.api.DataStreamWriter, com.clickhouse.data.ClickHouseFormat, com.clickhouse.client.api.insert.InsertSettings). com.clickhouse.client.api.DataStreamWriter est conçu pour implémenter une logique d’écriture de données personnalisée. Par exemple, pour lire des données depuis une file d’attente.

Lecture des données

  • Les données sont lues au format RowBinaryWithNamesAndTypes par défaut. À l’heure actuelle, seul ce format est pris en charge lorsqu’une liaison de données est nécessaire.
  • Les données peuvent être lues sous forme de collection d’enregistrements à l’aide de la méthode List<GenericRecord> com.clickhouse.client.api.Client#queryAll(java.lang.String). Cette méthode lit les données en mémoire puis libère la connexion. Aucune gestion supplémentaire n’est nécessaire. GenericRecord donne accès aux données et prend en charge certaines conversions.
Dernière modification le 2 juillet 2026