跳转到主要内容
用于通过协议与数据库服务器通信的 Java 客户端库。当前实现仅支持 HTTP interface。 该库提供了自有 API,用于向服务器发送请求,同时还提供了处理不同二进制数据格式 (RowBinary* & Native*) 的工具。

设置



初始化

Client 对象通过 com.clickhouse.client.api.Client.Builder#build() 初始化。每个客户端拥有独立的上下文,客户端之间不共享任何对象。 Builder 提供了多种配置方法,方便快速完成设置。示例:
showLineNumbers
Client 实现了 AutoCloseable 接口,不再需要时应将其关闭。

身份验证

身份验证在初始化阶段按客户端进行配置。支持三种身份验证方法:密码、访问令牌以及 SSL 客户端证书。通过密码进行身份验证需要调用 setUsername(String)setPassword(String) 来设置用户名和密码:
showLineNumbers
使用访问令牌进行身份验证需要调用 setAccessToken(String) 来设置访问令牌:
showLineNumbers
通过 SSL 客户端证书进行身份验证,需要分别调用 setUsername(String)useSSLAuthentication(boolean)setClientCertificate(String)setClientKey(String) 来设置用户名、启用 SSL 身份验证、设置客户端证书和客户端密钥:
showLineNumbers
在生产环境中,SSL 身份验证往往很难排查,因为 SSL 库返回的很多错误信息都不够充分。例如,如果客户端证书与密钥不匹配,server 会立即终止 connection (对于 HTTP,这会发生在 connection 建立阶段,此时还不会发送任何 HTTP request,因此也不会返回任何响应) 。请使用 openssl 等工具验证证书和密钥:
  • 检查密钥完整性:openssl rsa -in [key-file.key] -check -noout
  • 检查客户端证书是否包含与用户匹配的 CN:
    • 从用户证书中获取 CN:openssl x509 -noout -subject -in [user.cert]
    • 验证 database 中是否设置了相同的值:select name, auth_type, auth_params from system.users where auth_type = 'ssl_certificate' (该查询会输出 auth_params,类似 {"common_names":["some_user"]})

配置

所有设置均通过实例方法 (即配置方法) 定义,使每个值的作用域和上下文一目了然。 主要配置参数在单一作用域 (客户端或操作) 内定义,彼此之间不会相互覆盖。配置在客户端创建时定义。请参阅 com.clickhouse.client.api.Client.Builder

客户端配置


客户端识别

查询日志中有两个字段用于标识发起请求的应用程序:client_namehttp_user_agent。Native TCP 协议使用 client_name 标识应用程序,HTTP 协议使用 http_user_agent 标识应用程序。Client builder 提供了 setClientName 方法,可为两种协议正确设置相应的值。 字段 http_user_agent 遵循 User-Agent 请求头的通用格式:application-name[/version] [(operating-system; architecture; ...)]。 这组值会在每个 layer 中重复出现:应用程序层、客户端库层、HTTP 客户端库层。由 setClientName 方法设置的内容在列表中排在最前面。例如:
showLineNumbers
将产生以下 http_user_agent 值:
应用程序可以设置自定义 HTTP 请求头 User-Agent 来标识自身,但 clickhouse-java-v2/0.9.6-SNAPSHOT 部分会自动追加到该请求头的末尾。

操作标识

查询日志还有另外两个字段 query_idlog_comment,可用于标识操作并向查询日志添加额外信息。query_id 是操作的唯一标识符。应用程序可通过调用 QuerySettings 类的 setQueryId 方法来设置该值。
showLineNumbers
log_comment 是一个可以添加到查询日志中的注释。应用程序可以通过调用 QuerySettings 类的 logComment 方法来设置此注释。
showLineNumbers

服务器设置

服务器端配置可以在创建客户端时统一设置 (参见 BuilderserverSetting 方法) ,也可以在操作级别单独设置 (参见操作配置类的 serverSetting) 。
showLineNumbers
⚠️ 当通过 setOption 方法 (Client.Builder 或操作设置类) 设置选项时,server settings 名称应加上 clickhouse_setting_ 前缀。此时 com.clickhouse.client.api.ClientConfigProperties#serverSetting() 会很有帮助。

自定义 HTTP 请求头

可以为所有操作 (客户端级别) 或单个操作 (操作级别) 设置自定义 HTTP 请求头。
showLineNumbers
通过 setOption 方法 (Client.Builder 或操作设置类) 设置选项时,自定义请求头名称应以 http_header_ 为前缀。在这种情况下,com.clickhouse.client.api.ClientConfigProperties#httpHeader() 方法会很有帮助。

常用定义

ClickHouseFormat

支持格式的枚举类型,包含 ClickHouse 支持的所有格式。
  • raw - 用户应对原始数据进行转码
  • full - 客户端可以自行转码数据,并接收原始数据流
  • - - ClickHouse 不支持此格式的该操作
此客户端版本支持:

插入 API

insert(String tableName, InputStream data, ClickHouseFormat format)

以指定格式接受字节 InputStream 形式的数据。data 须以 format 指定的格式进行编码。签名
参数tableName - 目标表名称。data - 已编码数据的输入 stream。format - 数据编码所使用的格式。settings - 请求设置。返回值InsertResponse 类型的 Future——操作结果及附加信息,例如服务器端指标。示例
showLineNumbers

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

向数据库发送写请求。对象列表将被转换为高效格式后发送至服务器。列表项的类需要预先通过 register(Class, TableSchema) 方法注册。签名
参数tableName - 目标表的名称。data - 集合 DTO (数据传输对象) 对象。settings - 请求设置。返回值InsertResponse 类型的 Future——包含操作结果及服务端指标等附加信息。示例
showLineNumbers

InsertSettings

插入操作的配置选项。配置方法

InsertResponse

保存插入操作结果的响应对象。仅在客户端收到服务器响应时可用。
应尽快关闭此对象以释放连接,因为在完全读取前一个响应的所有数据之前,该连接无法重新使用。

查询 API

query(String sqlQuery)

按原样发送 sqlQuery。响应格式由查询设置决定。QueryResponse 将持有对响应 stream 的引用,该 stream 应由支持相应格式的读取器消费。签名
参数sqlQuery - 单条 SQL 语句。查询将按原样发送至服务器。settings - 请求设置。返回值QueryResponse 类型的 Future——包含结果数据集及服务端指标等附加信息。消费完数据集后,应关闭 Response 对象。示例

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

按原样发送 sqlQuery,同时发送查询参数,以便服务器编译 SQL 表达式。签名
参数sqlQuery - 带占位符 {} 的 SQL 表达式。queryParams - 用于在服务器端补全 SQL 表达式的变量映射。settings - 请求设置。返回值QueryResponse 类型的 Future——包含结果数据集及服务端指标等附加信息。消费完数据集后,应关闭 Response 对象。示例
showLineNumbers

queryAll(String sqlQuery)

RowBinaryWithNamesAndTypes 格式查询数据,并以集合形式返回结果。读取性能与使用 reader 时相同,但需要占用更多内存来存储完整的数据集。签名
参数sqlQuery - 用于从服务器查询数据的 SQL 表达式。返回值完整数据集,由一组 GenericRecord 对象列表表示,以行方式访问结果数据。示例
showLineNumbers

QuerySettings

查询操作的配置选项。配置方法

QueryResponse

保存查询执行结果的响应对象。仅当客户端收到来自服务器的响应时,该对象才可用。
应尽快关闭此对象以释放连接,因为在完全读取前一个响应的所有数据之前,该连接无法重新使用。

示例

  • 示例代码可在仓库中找到
  • 参考 Spring Service 的实现

通用 API

getTableSchema(String table)

拉取 table 的表 schema。签名
参数table - 需要拉取 schema 数据的表名。database - 目标表所在的数据库。返回值返回一个包含表列列表的 TableSchema 对象。

getTableSchemaFromQuery(String sql)

从 SQL 语句中拉取 schema。签名
参数sql - 需要返回其 schema 的 “SELECT” SQL 语句。返回值返回一个 TableSchema 对象,其列与 sql 表达式相匹配。

TableSchema

register(Class<?> clazz, TableSchema schema)

为 Java 类编译序列化与反序列化 layer,以便通过 schema 进行数据读写。该 method 将为 getter/setter 对及其对应列创建序列化器和反序列化器。 列的匹配通过从方法名中提取列名来实现。例如,getFirstName 对应的列为 first_namefirstname签名
参数clazz - 表示用于读取/写入数据的 POJO 的类。schema - 用于与 POJO 属性进行匹配的数据 schema。示例
showLineNumbers

使用示例

完整的示例代码存放在代码仓库的 ‘example` 文件夹中:

读取数据

读取数据有两种常见方式:
  • 返回底层 QueryResponse 对象的 query() 方法,该对象包含带有数据的 InputStream。通常会结合 ClickHouseBinaryFormatReader 用于流式读取,但 也可搭配任何其他自定义 reader 实现使用。QueryResponse 还提供对结果集元数据和指标的访问。
  • queryAll() 方法,并使用 GenericRecord 以便更方便地访问行。在这种情况下,整个结果集都会加载到内存中。
  • 返回 com.clickhouse.client.api.query.RecordsqueryRecords() 方法——它是一个用于遍历 GenericRecord 对象的迭代器。该方法采用流式方式 (不会将任何数据加载到内存中) ,并通过 GenericRecord 访问数据。
注意: 流式方法要求快速读取,否则可能导致服务器写入超时,因为数据是直接从网络流中读取的。

读取数组

ClickHouseBinaryFormatReader 方法
  • getList(...) - 将任意 Array(...) 读取为 List<T>。这是灵活类型读取的默认推荐选择。支持嵌套数组。
  • getByteArray(...), getShortArray(...), getIntArray(...), getLongArray(...), getFloatArray(...), getDoubleArray(...), getBooleanArray(...) - 最适合用于包含与基本类型兼容值的一维数组。
  • getStringArray(...) - 用于 Array(String) (以及以名称形式表示的枚举值) 。
  • getObjectArray(...) - 适用于任意 Array(...) 元素类型的通用选项,包括嵌套数组。可用于读取包含 Nullable 值和嵌套数组的数组。
所有方法均支持基于索引和基于名称的重载。索引从 1 开始计数。基于索引的方式可直接访问列。 基于名称的方法每次调用时均需执行索引查找。
GenericRecord 方法
  • getList(...) - 将任意 Array(...) 读取为 List<T>。这是灵活类型读取的默认推荐选择。支持嵌套数组。
  • getByteArray(...), getShortArray(...), getIntArray(...), getLongArray(...), getFloatArray(...), getDoubleArray(...), getBooleanArray(...) - 最适合用于包含与基本类型兼容值的一维数组。
  • getStringArray(...) - 用于 Array(String) (以及以名称形式表示的枚举值) 。
  • getObjectArray(...) - 适用于任意 Array(...) 元素类型的通用选项,包括嵌套数组。可用于读取包含 Nullable 值和嵌套数组的数组。
所有方法均支持基于索引和基于名称的重载。索引从 1 开始计数。基于索引的方式可直接访问列。 基于名称的方法每次调用时均需执行索引查找。

迁移指南

旧版客户端 (V1) 以 com.clickhouse.client.ClickHouseClient#builder 作为起点。新版客户端 (V2) 采用类似的模式,使用 com.clickhouse.client.api.Client.Builder。主要区别如下:
  • 未使用服务加载器来获取具体实现。com.clickhouse.client.api.Client 是一个门面类,未来可适配各种实现。
  • 配置来源更少:一类提供给构建器,另一类在操作设置 (QuerySettingsInsertSettings) 中。先前版本会为每个节点分别配置,并且在某些情况下会加载 环境变量。

配置参数匹配

V1 中有 3 个与配置相关的枚举类:
  • com.clickhouse.client.config.ClickHouseDefaults - 在大多数情况下都需要设置的配置参数,例如 USERPASSWORD
  • com.clickhouse.client.config.ClickHouseClientOption - 客户端特有的配置参数,例如 HEALTH_CHECK_INTERVAL
  • com.clickhouse.client.http.config.ClickHouseHttpOption - HTTP 接口专用的配置参数,例如 RECEIVE_QUERY_PROGRESS
这些设计的初衷是对参数进行分组并实现清晰的隔离。然而在某些情况下,这反而造成了混淆 (例如,com.clickhouse.client.config.ClickHouseDefaults#ASYNCcom.clickhouse.client.config.ClickHouseClientOption#ASYNC 之间究竟有何区别?) 。新的 V2 客户端以 com.clickhouse.client.api.Client.Builder 作为所有可用客户端配置选项的统一字典。所有配置参数名称均列于 com.clickhouse.client.api.ClientConfigProperties 中。下表列出了新客户端中支持的旧选项及其新含义。图例: ✔ = 支持,✗ = 已丢弃

主要差异

  • Client V2 使用更少的专有类,以提高可移植性。例如,V2 可配合 java.io.InputStream 的任何实现来 将数据写入服务器。
  • Client V2 的 async 设置默认值为 off。这意味着不会额外创建线程,且应用程序对客户端有更强的控制能力。对于绝大多数用例,此设置都应保持为 off。启用 async 会为每个请求创建一个单独的线程。只有在使用由应用程序控制的 executor 时,这样做才有意义 (请参见 com.clickhouse.client.api.Client.Builder#setSharedOperationExecutor)

写入数据

  • 可使用 java.io.InputStream 的任何实现。支持 V1 com.clickhouse.data.ClickHouseInputStream,但不建议使用。
  • 一旦检测到输入流结束,就会进行相应处理。在此之前,应关闭请求的输出流。
V1 插入 TSV 格式的数据。
V2 插入 TSV 格式数据。
  • 只需调用一个方法。无需另外创建请求对象。
  • 请求体流会在所有数据复制完毕后自动关闭。
  • 现已提供新的底层 API: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 用于实现自定义的数据写入逻辑。例如,从 队列中读取数据。

读取数据

  • 默认使用 RowBinaryWithNamesAndTypes 格式读取数据。当前在需要进行数据绑定时,仅支持此格式。
  • 可以使用 List<GenericRecord> com.clickhouse.client.api.Client#queryAll(java.lang.String) 方法,将数据作为记录集合读取。它会将数据读入内存并释放连接,无需额外处理。GenericRecord 提供对数据的访问,并支持一些类型转换。
最后修改于 2026年7月2日