Saltar al contenido principal
Biblioteca cliente de Java para comunicarse con un servidor de base de datos a través de sus protocolos. La implementación actual solo admite la interfaz HTTP. La biblioteca ofrece su propia API para enviar solicitudes a un servidor, y también incluye herramientas para trabajar con distintos formatos de datos binarios (RowBinary* & Native*).

Configuración



Inicialización

El objeto Client se inicializa mediante com.clickhouse.client.api.Client.Builder#build(). Cada cliente tiene su propio contexto y no se comparten objetos entre ellos. El Builder dispone de métodos de configuración para simplificar la configuración.Ejemplo:
showLineNumbers
Client es AutoCloseable y debe cerrarse cuando ya no se necesite.

Autenticación

La autenticación se configura por cliente en la fase de inicialización. Se admiten tres métodos de autenticación: por contraseña, por token de acceso y por certificado de cliente SSL.La autenticación mediante contraseña requiere configurar el nombre de usuario y la contraseña llamando a setUsername(String) y setPassword(String):
showLineNumbers
La autenticación mediante un token de acceso requiere establecer el token de acceso llamando a setAccessToken(String):
showLineNumbers
La autenticación mediante un certificado de cliente SSL requiere configurar el nombre de usuario, habilitar la autenticación SSL, y establecer un certificado de cliente y una clave de cliente mediante las llamadas a setUsername(String), useSSLAuthentication(boolean), setClientCertificate(String) y setClientKey(String) respectivamente:
showLineNumbers
La autenticación SSL puede ser difícil de diagnosticar en producción porque muchos errores de las bibliotecas SSL no proporcionan información suficiente. Por ejemplo, si el certificado del cliente y la clave no coinciden, el servidor cerrará la conexión de inmediato (en el caso de HTTP, esto ocurrirá durante la fase de inicio de la conexión, cuando no se envía ninguna solicitud HTTP, por lo que no se envía ninguna respuesta).Utilice herramientas como openssl para verificar certificados y claves:
  • comprobar la integridad de la clave: openssl rsa -in [key-file.key] -check -noout
  • comprobar que el certificado del cliente tenga un CN que coincida con un usuario:
    • obtener el CN de un certificado de usuario: openssl x509 -noout -subject -in [user.cert]
    • verificar que el mismo valor esté establecido en la base de datos select name, auth_type, auth_params from system.users where auth_type = 'ssl_certificate' (la consulta mostrará auth_params con algo como {"common_names":["some_user"]})

Configuración

Todas las configuraciones se definen mediante métodos de instancia (también conocidos como métodos de configuración) que hacen explícitos el alcance y el contexto de cada valor. Los principales parámetros de configuración se definen en un único ámbito (cliente u operación) y no se sobrescriben entre sí.La configuración se define durante la creación del cliente. Consulte com.clickhouse.client.api.Client.Builder.

Configuración del cliente


Identificación del cliente

Hay dos campos en el log de consultas que identifican la aplicación que originó una solicitud: client_name y http_user_agent. El protocolo TCP nativo utiliza client_name para identificar la aplicación. El protocolo HTTP utiliza http_user_agent para identificar la aplicación. El constructor del cliente dispone del método setClientName para establecer los valores correctos en ambos protocolos. El campo http_user_agent se establece según el formato común del header User-Agent: application-name[/version] [(operating-system; architecture; ...)]. Este conjunto de valores se repite para cada capa: aplicación, biblioteca cliente y biblioteca cliente HTTP. Lo que establece el método setClientName aparece primero en la lista.Por ejemplo:
showLineNumbers
dará como resultado el siguiente valor de http_user_agent:
La aplicación puede establecer su propio encabezado HTTP User-Agent para identificarse. No obstante, el fragmento clickhouse-java-v2/0.9.6-SNAPSHOT se añadirá al final del encabezado.

Identificación de operaciones

El registro de consultas cuenta con otros dos campos, query_id y log_comment, que pueden utilizarse para identificar una operación y agregar información adicional al registro de consultas.query_id es un identificador único de una operación. La aplicación puede establecerlo llamando al método setQueryId de la clase QuerySettings.
showLineNumbers
log_comment es un comentario que se puede añadir al registro de consultas. Las aplicaciones pueden establecerlo llamando al método logComment de la clase QuerySettings.
showLineNumbers

Configuración del servidor

Los ajustes del lado del servidor pueden configurarse a nivel de cliente una sola vez durante la creación (consulte el método serverSetting de Builder) y a nivel de operación (consulte serverSetting en la clase de ajustes de operación).
showLineNumbers
⚠️ Cuando las opciones se configuran mediante el método setOption (ya sea en Client.Builder o en la clase de configuración de operaciones), el nombre de los server settings debe ir precedido del prefijo clickhouse_setting_. En este caso, com.clickhouse.client.api.ClientConfigProperties#serverSetting() puede resultar de utilidad.

Encabezado HTTP personalizado

Se pueden configurar HTTP headers personalizados para todas las operaciones (nivel de cliente) o para una sola (nivel de operación).
showLineNumbers
Cuando las opciones se configuran mediante el método setOption (ya sea en Client.Builder o en la clase de configuración de operaciones), el nombre del encabezado personalizado debe llevar el prefijo http_header_. El método com.clickhouse.client.api.ClientConfigProperties#httpHeader() puede ser de utilidad en este caso.

Definiciones comunes

ClickHouseFormat

Enum de formatos compatibles. Incluye todos los formatos admitidos por ClickHouse.
  • raw - el usuario debe transcodificar los datos sin procesar
  • full - el cliente puede transcodificar datos por su cuenta y acepta un flujo de datos sin procesar
  • - - operación no admitida por ClickHouse para este formato
Esta versión del cliente admite:

API de inserción

insert(String tableName, InputStream data, ClickHouseFormat format)

Acepta datos como un InputStream de bytes en el formato especificado. Se espera que data esté codificado en el format.Firmas
ParámetrostableName - nombre de la tabla de destino.data - un flujo de entrada de datos codificados.format - un formato en el que se codifican los datos.settings - parámetros de la solicitud.Valor de retornoFuture del tipo InsertResponse: resultado de la operación e información adicional como las métricas del lado del servidor.Ejemplos
showLineNumbers

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

Envía una solicitud de escritura a la base de datos. La lista de objetos se convierte a un formato eficiente y luego se envía al servidor. La clase de los elementos de la lista debe registrarse de antemano mediante el método register(Class, TableSchema).Firmas
ParámetrostableName - nombre de la tabla de destino.data - objetos DTO (Data Transfer Object) de colección.settings - parámetros de la solicitud.Valor de retornoFuture del tipo InsertResponse: el resultado de la operación e información adicional como las métricas del lado del servidor.Ejemplos
showLineNumbers

InsertSettings

Opciones de configuración para operaciones de inserción.Métodos de configuración

InsertResponse

Objeto de respuesta que contiene el resultado de la operación de inserción. Solo está disponible si el cliente recibió una respuesta del servidor.
Este objeto debe cerrarse lo antes posible para liberar una conexión, ya que esta no puede reutilizarse hasta que se hayan leído por completo todos los datos de la respuesta anterior.

API de consultas

query(String sqlQuery)

Envía sqlQuery tal cual. El formato de respuesta se determina mediante la configuración de la consulta. QueryResponse contendrá una referencia al flujo de respuesta que debe ser consumido por un lector para el formato compatible.Firmas
ParámetrossqlQuery - una única sentencia SQL. La consulta se envía tal como está al servidor.settings - parámetros de la solicitud.Valor de retornoFuture del tipo QueryResponse: un conjunto de datos de resultado e información adicional como las métricas del lado del servidor. El objeto Response debe cerrarse tras consumir el conjunto de datos.Ejemplos

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

Envía sqlQuery tal cual. Además, enviará los parámetros de consulta para que el servidor pueda compilar la expresión SQL.Firmas
ParámetrossqlQuery - expresión SQL con marcadores de posición {}.queryParams - mapa de variables para completar la expresión SQL en el servidor.settings - parámetros de la solicitud.Valor de retornoFuture del tipo QueryResponse: un conjunto de datos de resultado e información adicional como las métricas del lado del servidor. El objeto Response debe cerrarse tras consumir el conjunto de datos.Ejemplos
showLineNumbers

queryAll(String sqlQuery)

Consulta datos en formato RowBinaryWithNamesAndTypes. Devuelve el resultado como una colección. El rendimiento de lectura es el mismo que con el lector, pero se necesita más memoria para almacenar el conjunto de datos completo.Firmas
ParámetrossqlQuery - expresión SQL para consultar datos desde un servidor.Valor de retornoConjunto de datos completo representado por una lista de objetos GenericRecord que proporcionan acceso por filas a los datos del resultado.Ejemplos
showLineNumbers

QuerySettings

Opciones de configuración para operaciones de consulta.Métodos de configuración

QueryResponse

Objeto de respuesta que contiene el resultado de la ejecución de la consulta. Solo está disponible si el cliente recibió una respuesta del servidor.
Este objeto debe cerrarse lo antes posible para liberar una conexión, ya que esta no puede reutilizarse hasta que se hayan leído por completo todos los datos de la respuesta anterior.

Ejemplos

API común

getTableSchema(String table)

Obtiene el esquema de la tabla para table.Firmas
Parámetrostable - nombre de la tabla de la que se deben obtener los datos del esquema.database - base de datos donde se define la tabla de destino.Valor de retornoDevuelve un objeto TableSchema con la lista de columnas de la tabla.

getTableSchemaFromQuery(String sql)

Obtiene el esquema a partir de una instrucción SQL.Firmas
Parámetrossql - Sentencia SQL “SELECT” cuyo esquema se desea obtener.Valor de retornoDevuelve un objeto TableSchema con columnas que coinciden con la expresión sql.

TableSchema

register(Class<?> clazz, TableSchema schema)

Compila la capa de serialización y deserialización para la clase Java que se utilizará para escribir y leer datos con schema. El método creará un serializador y un deserializador para el par getter/setter y la columna correspondiente. La coincidencia de columna se determina extrayendo su nombre a partir del nombre del método. Por ejemplo, getFirstName corresponderá a la columna first_name o firstname.Firmas
Parámetrosclazz - Clase que representa el POJO utilizado para leer/escribir datos.schema - Esquema de datos que se usará para hacer coincidir con las propiedades POJO.Ejemplos
showLineNumbers

Ejemplos de uso

El código de ejemplos completo está almacenado en el repositorio en la carpeta ‘example`:
  • client-v2 - colección principal de ejemplos.
  • demo-service - ejemplo de cómo utilizar el cliente en una aplicación Spring Boot.
  • demo-kotlin-service - ejemplo de cómo usar el cliente en una aplicación de Ktor (Kotlin).

Lectura de datos

Hay dos formas comunes de leer datos:
  • método query() que devuelve un objeto QueryResponse de bajo nivel que contiene un InputStream con datos. Normalmente se combina con ClickHouseBinaryFormatReader para lecturas en streaming, pero puede utilizarse con cualquier otra implementación personalizada de lector. QueryResponse también proporciona acceso a los metadatos del conjunto de resultados y a las métricas.
  • método queryAll() y uso de GenericRecord para acceder cómodamente a las filas. En este caso, todo el conjunto de resultados se carga en memoria.
  • método queryRecords() que devuelve com.clickhouse.client.api.query.Records: un iterador de objetos GenericRecord. Este método utiliza un enfoque de streaming (no se cargan datos en memoria) y usa GenericRecord para acceder a los datos.
Nota: el enfoque de streaming requiere una lectura rápida; de lo contrario, puede provocar un timeout de escritura en el servidor, ya que los datos se leen directamente desde el stream de red.

Lectura de Arrays

Métodos de ClickHouseBinaryFormatReader
  • getList(...) - lee cualquier Array(...) como List<T>. Es una buena opción predeterminada para lecturas flexibles con tipado. Admite arrays anidados.
  • getByteArray(...), getShortArray(...), getIntArray(...), getLongArray(...), getFloatArray(...), getDoubleArray(...), getBooleanArray(...) - mejor para arrays 1D de valores compatibles con tipos primitivos.
  • getStringArray(...) - para Array(String) (y valores de enum representados por nombres).
  • getObjectArray(...) - opción genérica para cualquier tipo de elemento de Array(...), incluidos los arrays anidados. Úselo para leer arrays con valores anulables y arrays anidados.
Las sobrecargas basadas en índice y en nombre están disponibles para todos los métodos. El índice es base 1. Las sobrecargas basadas en índice realizan acceso directo a una columna. Los métodos basados en nombre requieren una búsqueda por índice en cada invocación.
Métodos de GenericRecord
  • getList(...) - lee cualquier Array(...) como List<T>. Buena opción predeterminada para lecturas flexibles con tipado. Admite arrays anidados.
  • getByteArray(...), getShortArray(...), getIntArray(...), getLongArray(...), getFloatArray(...), getDoubleArray(...), getBooleanArray(...) - ideal para arrays unidimensionales de valores compatibles con tipos primitivos.
  • getStringArray(...) - para Array(String) (y valores de enum representados por nombres).
  • getObjectArray(...) - opción genérica para cualquier tipo de elemento de Array(...), incluidos los arrays anidados. Úsela para leer arrays con valores que admiten NULL y arrays anidados.
Las sobrecargas basadas en índice y en nombre están disponibles para todos los métodos. El índice es base 1. Las sobrecargas basadas en índice realizan acceso directo a una columna. Los métodos basados en nombre requieren una búsqueda por índice en cada invocación.

Guía de migración

El cliente antiguo (V1) utilizaba com.clickhouse.client.ClickHouseClient#builder como punto de partida. El nuevo cliente (V2) usa un patrón similar con com.clickhouse.client.api.Client.Builder. Las principales diferencias son:
  • no se utiliza ningún cargador de servicios para obtener la implementación. com.clickhouse.client.api.Client es una clase fachada para todo tipo de implementaciones futuras.
  • menos fuentes de configuración: una se proporciona al builder y otra se encuentra en la configuración de operación (QuerySettings, InsertSettings). La versión anterior tenía una configuración por nodo y, en algunos casos, cargaba variables de entorno.

Coincidencia de parámetros de configuración

Hay 3 clases enum relacionadas con la configuración en V1:
  • com.clickhouse.client.config.ClickHouseDefaults - parámetros de configuración que suelen establecerse en la mayoría de los casos de uso, como USER y PASSWORD.
  • com.clickhouse.client.config.ClickHouseClientOption - parámetros de configuración específicos para el cliente, como HEALTH_CHECK_INTERVAL.
  • com.clickhouse.client.http.config.ClickHouseHttpOption - parámetros de configuración específicos de la interfaz HTTP, como RECEIVE_QUERY_PROGRESS.
Fueron diseñados para agrupar parámetros y ofrecer una separación clara. Sin embargo, en algunos casos esto generaba confusión (¿hay alguna diferencia entre com.clickhouse.client.config.ClickHouseDefaults#ASYNC y com.clickhouse.client.config.ClickHouseClientOption#ASYNC?). El nuevo cliente V2 utiliza com.clickhouse.client.api.Client.Builder como diccionario único de todas las opciones de configuración posibles del cliente. En com.clickhouse.client.api.ClientConfigProperties se encuentran listados todos los nombres de parámetros de configuración.La siguiente tabla muestra qué opciones antiguas son compatibles con el nuevo cliente y su nuevo significado.Leyenda: ✔ = compatible, ✗ = eliminado

Diferencias generales

  • Client V2 utiliza menos clases propietarias para aumentar la portabilidad. Por ejemplo, V2 funciona con cualquier implementación de java.io.InputStream para escribir datos en un servidor.
  • La configuración async de Client V2 está off de forma predeterminada. Esto significa que no hay hilos adicionales y que la aplicación tiene un mayor control sobre el cliente. Esta configuración debería estar off en la mayoría de los casos de uso. Al habilitar async, se creará un hilo independiente para cada solicitud. Solo tiene sentido cuando se usa un executor controlado por la aplicación (consulte com.clickhouse.client.api.Client.Builder#setSharedOperationExecutor)

Escritura de datos

  • usa cualquier implementación de java.io.InputStream. Se admite V1 com.clickhouse.data.ClickHouseInputStream, pero NO se recomienda.
  • Una vez detectado el final del flujo de entrada, se actúa en consecuencia. Antes, debe cerrarse el flujo de salida de una solicitud.
V1 Insertar datos con formato TSV.
V2 Insertar datos con formato TSV.
  • solo hay que llamar a un único método. No es necesario crear un objeto de solicitud adicional.
  • el flujo del cuerpo de la solicitud se cierra automáticamente cuando se copian todos los datos.
  • hay una nueva API de bajo nivel 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á diseñada para implementar lógica personalizada de escritura de datos. Por ejemplo, leer datos de una cola.

Lectura de datos

  • Los datos se leen en el formato RowBinaryWithNamesAndTypes de forma predeterminada. Actualmente, solo se admite este formato cuando se requiere el enlace de datos.
  • Los datos pueden leerse como una colección de registros mediante el método List<GenericRecord> com.clickhouse.client.api.Client#queryAll(java.lang.String). Este método lee los datos en memoria y libera la conexión. No requiere ninguna gestión adicional. GenericRecord proporciona acceso a los datos e implementa algunas conversiones.
Última modificación el 2 de julio de 2026