Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Java クライアント

DBサーバーとそのプロトコルを通じて通信するための Java クライアントライブラリです。現在の実装は HTTP インターフェイス のみをサポートしています。 このライブラリはサーバーへリクエストを送信するための独自の API を提供します。また、さまざまなバイナリデータフォーマット (RowBinary* & Native*) を扱うためのツールも提供しています。

セットアップ


<dependency>
    <groupId>com.clickhouse</groupId>
    <artifactId>client-v2</artifactId>
    <version>0.9.8</version>
</dependency>

初期化

Client オブジェクトは com.clickhouse.client.api.Client.Builder#build() によって初期化されます。各クライアントは独自のコンテキストを持ち、クライアント間でオブジェクトが共有されることはありません。 Builder には、便利な設定メソッドが用意されています。

例:

 Client client = new Client.Builder()
                .addEndpoint("https://clickhouse-cloud-instance:8443/")
                .setUsername(user)
                .setPassword(password)
                .build();

ClientAutoCloseable であり、不要になったらクローズしてください。

認証

認証は初期化フェーズでクライアントごとに設定されます。サポートされる認証方式は 3 種類あります:パスワード、アクセストークン、SSL クライアント証明書。

パスワードによる認証を行うには、setUsername(String) および setPassword(String) を呼び出してユーザー名とパスワードを設定する必要があります。

 Client client = new Client.Builder()
        .addEndpoint("https://clickhouse-cloud-instance:8443/")
        .setUsername(user)
        .setPassword(password)
        .build();

アクセストークンによる認証を行うには、setAccessToken(String) を呼び出してアクセストークンを設定する必要があります。

 Client client = new Client.Builder()
        .addEndpoint("https://clickhouse-cloud-instance:8443/")
        .setAccessToken(userAccessToken)
        .build();

SSLクライアント証明書による認証を行うには、setUsername(String)useSSLAuthentication(boolean)setClientCertificate(String)、および setClientKey(String) をそれぞれ呼び出して、ユーザー名の設定、SSL認証の有効化、クライアント証明書とクライアント秘密鍵の設定を行う必要があります。

Client client = new Client.Builder()
        .useSSLAuthentication(true)
        .setUsername("some_user")
        .setClientCertificate("some_user.crt")
        .setClientKey("some_user.key")

設定

すべての設定は、各値のスコープとコンテキストが明確になるように、インスタンスメソッド (別名: 設定メソッド) で定義されています。 主要な設定パラメーターは、単一のスコープ (クライアントまたは操作) で定義され、互いに上書きしません。

設定はクライアントの作成時に定義されます。com.clickhouse.client.api.Client.Builder を参照してください。

クライアント設定

メソッド 引数 説明 デフォルト キー
addEndpoint(String endpoint) endpoint - URL形式のサーバーアドレス 利用可能なサーバーの一覧にサーバーのエンドポイントを追加します。現在サポートされているエンドポイントは1つのみです。 none none
addEndpoint(Protocol protocol, String host, int port, boolean secure) protocol - 接続プロトコル
host - IPアドレスまたはホスト名
secure - HTTPSを使用
利用可能なサーバーの一覧にサーバーのエンドポイントを追加します。現在サポートされているエンドポイントは1つのみです。 none none
enableConnectionPool(boolean enable) enable - 有効/無効を切り替えるフラグ 接続プールを有効にするかどうかを設定します true connection_pool_enabled
setMaxConnections(int maxConnections) maxConnections - 接続数 クライアントが各サーバーのエンドポイントに対して開ける接続数を設定します。 10 max_open_connections
setConnectionTTL(long timeout, ChronoUnit unit) timeout - タイムアウト値
unit - 時間単位
接続が非アクティブと見なされるまでの有効期限 (TTL) を設定します -1 connection_ttl
setKeepAliveTimeout(long timeout, ChronoUnit unit) timeout - タイムアウト値
unit - 時間単位
HTTP接続の Keep-Alive タイムアウトを設定します。0 に設定すると Keep-Alive は無効になります。 - http_keep_alive_timeout
setConnectionReuseStrategy(ConnectionReuseStrategy strategy) strategy - LIFO または FIFO 接続プールで使用する戦略を選択します FIFO connection_reuse_strategy
setDefaultDatabase(String database) database - データベース名 デフォルトのデータベースを設定します。 default database

クライアントの識別

クエリログには、リクエストの送信元アプリケーションを識別する2つのフィールドがあります: client_namehttp_user_agent です。ネイティブTCPプロトコルはアプリケーションの識別に client_name を使用し、HTTPプロトコルは http_user_agent を使用します。クライアントビルダーには、両プロトコルに対して正しい値を設定するメソッド setClientName があります。 フィールド http_user_agent は、User-Agent ヘッダーの一般的なフォーマットに従って設定されます: application-name[/version] [(operating-system; architecture; ...)]。 この値のセットは、アプリケーション、クライアントライブラリ、HTTPクライアントライブラリという各レイヤーに対して繰り返されます。setClientName メソッドで設定された値がリストの先頭に配置されます。

例:

client.setClientName("my-app-01/1.0");

結果として、http_user_agent の値は次のようになります。

my-app-01/1.0 clickhouse-java-v2/0.9.6-SNAPSHOT (Linux; jvm:17.0.17) Apache-HttpClient/5.4.4

アプリケーションは、自身を識別するために独自の HTTP ヘッダー User-Agent を設定できます。ただし、clickhouse-java-v2/0.9.6-SNAPSHOT の部分がヘッダーの末尾に追加されます。

オペレーションの識別

クエリログには、操作の識別やクエリログへの追加情報の付加に使用できる query_idlog_comment という2つのフィールドがあります。

query_id は操作の一意の識別子です。アプリケーションは QuerySettings クラスの setQueryId メソッドを呼び出して設定できます。

QuerySettings querySettings = new QuerySettings();
querySettings.setQueryId("some-query-id");

log_comment は、クエリログに追加できるコメントです。アプリケーションから QuerySettings クラスの logComment メソッドを呼び出して設定できます。

QuerySettings querySettings = new QuerySettings();
querySettings.logComment("some-comment");

サーバー設定

サーバー側の設定は、クライアントレベルでは作成時に一度設定できます (BuilderserverSetting メソッドを参照) 。また、オペレーションレベルでも設定できます (オペレーション設定クラスの serverSetting を参照) 。

 try (Client client = new Client.Builder().addEndpoint(Protocol.HTTP, "localhost", mockServer.port(), false)
        .setUsername("default")
        .setPassword(ClickHouseServerForTest.getPassword())
        .compressClientRequest(true)

        // Client level
        .serverSetting("max_threads", "10")
        .serverSetting("async_insert", "1")
        .serverSetting("roles", Arrays.asList("role1", "role2"))

        .build()) {

	// Operation level
	QuerySettings querySettings = new QuerySettings();
	querySettings.serverSetting("session_timezone", "Europe/Zurich");

	...
}

⚠️ setOption メソッド (Client.Builder または操作設定クラス) でオプションを設定する場合、サーバー設定名には clickhouse_setting_ というプレフィックスを付ける必要があります。この場合、com.clickhouse.client.api.ClientConfigProperties#serverSetting() を使用すると便利です。

カスタム HTTP ヘッダー

カスタムHTTPヘッダーは、すべての操作 (クライアントレベル) または個別の操作 (オペレーションレベル) に設定できます。


QuerySettings settings = new QuerySettings()
    .httpHeader(HttpHeaders.REFERER, clientReferer)
    .setQueryId(qId);

setOption メソッド (Client.Builder または操作設定クラス) でオプションを設定する場合、カスタムヘッダー名には http_header_ をプレフィックスとして付ける必要があります。この場合、com.clickhouse.client.api.ClientConfigProperties#httpHeader() メソッドが便利です。

共通の定義

ClickHouseFormat

対応フォーマットのenumです。ClickHouseがサポートするすべてのフォーマットを含みます。

  • raw - ユーザーは生データをトランスコードする必要があります
  • full - クライアント自身でデータをトランスコードでき、raw データストリームを受け入れます
  • - - このフォーマットでは、ClickHouse はこの操作をサポートしていません

このクライアントバージョンでは以下をサポートしています:

フォーマット 入力 出力
TabSeparated raw raw
TabSeparatedRaw raw raw
TabSeparatedWithNames raw raw
TabSeparatedWithNamesAndTypes raw raw
TabSeparatedRawWithNames raw raw
TabSeparatedRawWithNamesAndTypes raw raw
Template raw raw
TemplateIgnoreSpaces raw -
CSV raw raw
CSVWithNames raw raw
CSVWithNamesAndTypes raw raw
CustomSeparated raw raw
CustomSeparatedWithNames raw raw
CustomSeparatedWithNamesAndTypes raw raw
SQLInsert - raw
Values raw raw
Vertical - raw
JSON raw raw
JSONAsString raw -
JSONAsObject raw -
JSONStrings raw raw
JSONColumns raw raw
JSONColumnsWithMetadata raw raw
JSONCompact raw raw
JSONCompactStrings - raw
JSONCompactColumns raw raw
JSONEachRow raw raw
PrettyJSONEachRow - raw
JSONEachRowWithProgress - raw
JSONStringsEachRow raw raw
JSONStringsEachRowWithProgress - raw
JSONCompactEachRow raw raw
JSONCompactEachRowWithNames raw raw
JSONCompactEachRowWithNamesAndTypes raw raw
JSONCompactStringsEachRow raw raw
JSONCompactStringsEachRowWithNames raw raw
JSONCompactStringsEachRowWithNamesAndTypes raw raw
JSONObjectEachRow raw raw
BSONEachRow raw raw
TSKV raw raw
Pretty - raw
PrettyNoEscapes - raw
PrettyMonoBlock - raw
PrettyNoEscapesMonoBlock - raw
PrettyCompact - raw
PrettyCompactNoEscapes - raw
PrettyCompactMonoBlock - raw
PrettyCompactNoEscapesMonoBlock - raw
PrettySpace - raw
PrettySpaceNoEscapes - raw
PrettySpaceMonoBlock - raw
PrettySpaceNoEscapesMonoBlock - raw
Prometheus - raw
Protobuf raw raw
ProtobufSingle raw raw
ProtobufList raw raw
Avro raw raw
AvroConfluent raw -
Parquet raw raw
ParquetMetadata raw -
Arrow raw raw
ArrowStream raw raw
ORC raw raw
One raw -
Npy raw raw
RowBinary full full
RowBinaryWithNames full full
RowBinaryWithNamesAndTypes full full
RowBinaryWithDefaults full -
Native full raw
Null - raw
XML - raw
CapnProto raw raw
LineAsString raw raw
Regexp raw -
RawBLOB raw raw
MsgPack raw raw
MySQLDump raw -
DWARF raw -
Markdown - raw
Form raw -

Insert API

insert(String tableName, InputStream data, ClickHouseFormat format)

指定されたフォーマットのバイト列を InputStream として受け取ります。dataformat でエンコードされていることが前提です。

シグネチャ

CompletableFuture<InsertResponse> insert(String tableName, InputStream data, ClickHouseFormat format, InsertSettings settings)
CompletableFuture<InsertResponse> insert(String tableName, InputStream data, ClickHouseFormat format)

パラメーター

tableName - ターゲットテーブルの名前。

data - エンコードされたデータの入力ストリーム。

format - データのエンコードに使用するフォーマット。

settings - リクエストの設定。

戻り値

InsertResponse 型の Future — 操作の結果およびサーバー側のメトリクスなどの追加情報。

try (InputStream dataStream = getDataStream()) {
    try (InsertResponse response = client.insert(TABLE_NAME, dataStream, ClickHouseFormat.JSONEachRow,
            insertSettings).get(3, TimeUnit.SECONDS)) {

        log.info("Insert finished: {} rows written", response.getMetrics().getMetric(ServerMetrics.NUM_ROWS_WRITTEN).getLong());
    } catch (Exception e) {
        log.error("Failed to write JSONEachRow data", e);
        throw new RuntimeException(e);
    }
}

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

データベースへ書き込みリクエストを送信します。オブジェクトのリストは効率的なフォーマットに変換され、サーバーに送信されます。リスト要素のクラスは、register(Class, TableSchema) メソッドを使用して事前に登録しておく必要があります。

シグネチャ

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

パラメーター

tableName - ターゲットテーブルの名前。

data - コレクションDTO (Data Transfer Object) オブジェクト。

settings - リクエストの設定。

戻り値

InsertResponse 型のFuture — 操作の結果およびサーバーサイドのメトリクスなどの追加情報。

// Important step (done once) - register class to pre-compile object serializer according to the table schema.
client.register(ArticleViewEvent.class, client.getTableSchema(TABLE_NAME));

List<ArticleViewEvent> events = loadBatch();

try (InsertResponse response = client.insert(TABLE_NAME, events).get()) {
    // handle response, then it will be closed and connection that served request will be released.
}

InsertSettings

挿入操作の設定オプション。

設定方法

メソッド 説明
setQueryId(String queryId) 操作に割り当てるクエリ ID を設定します。デフォルト: null
setDeduplicationToken(String token) 重複排除トークンを設定します。このトークンはサーバーに送信され、クエリの識別子として使用できます。デフォルト: null
setInputStreamCopyBufferSize(int size) コピーバッファのサイズ。書き込み処理時に、ユーザー指定の入力ストリームから出力ストリームへデータをコピーするために使用されるバッファです。デフォルト: 8196
serverSetting(String name, String value) 操作に対する個別のサーバー設定を行います。
serverSetting(String name, Collection values) 操作に対して、個別のサーバー設定に複数の値を設定します。コレクションの各項目は String 値である必要があります。
setDBRoles(Collection dbRoles) 操作の実行前に設定する DB ロールを指定します。コレクションの項目は String 値である必要があります。
setOption(String option, Object value) 構成オプションを生の形式で設定します。これはサーバー設定ではありません。

InsertResponse

insertオペレーションの結果を保持するレスポンスオブジェクトです。クライアントがサーバーからレスポンスを受け取った場合にのみ使用できます。

メソッド 説明
OperationMetrics getMetrics() 操作のメトリクスを含むオブジェクトを返します。
String getQueryId() アプリケーション (操作設定またはサーバー経由) によってこの操作に割り当てられたクエリ ID を返します。

クエリ API

query(String sqlQuery)

sqlQuery をそのまま送信します。レスポンスのフォーマットはクエリの設定によって決まります。QueryResponse はレスポンスストリームへの参照を保持し、対応するフォーマットのリーダーによって読み取られる必要があります。

シグネチャ

CompletableFuture<QueryResponse> query(String sqlQuery, QuerySettings settings)
CompletableFuture<QueryResponse> query(String sqlQuery)

パラメーター

sqlQuery - 単一のSQLステートメント。クエリはそのままサーバーに送信されます。

settings - リクエストの設定。

戻り値

QueryResponse 型のFuture — 結果データセットおよびサーバーサイドのメトリクスなどの追加情報を含みます。Responseオブジェクトは、データセットを使用した後にクローズする必要があります。

final String sql = "select * from " + TABLE_NAME + " where title <> '' limit 10";

// Default format is RowBinaryWithNamesAndTypesFormatReader so reader have all information about columns
try (QueryResponse response = client.query(sql).get(3, TimeUnit.SECONDS);) {

    // Create a reader to access the data in a convenient way
    ClickHouseBinaryFormatReader reader = client.newBinaryFormatReader(response);

    while (reader.hasNext()) {
        reader.next(); // Read the next record from stream and parse it

        // get values
        double id = reader.getDouble("id");
        String title = reader.getString("title");
        String url = reader.getString("url");

        // collecting data
    }
} catch (Exception e) {
    log.error("Failed to read data", e);
}

// put business logic outside of the reading block to release http connection asap.

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

sqlQuery をそのまま送信します。また、サーバーがSQL式をコンパイルできるように、クエリパラメータも送信します。

署名

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

パラメーター

sqlQuery - プレースホルダー {} を含む SQL 式。

queryParams - サーバー上で SQL 式を完成させるための変数を格納するマップ。

settings - リクエストの設定。

戻り値

QueryResponse 型のFuture — 結果データセットおよびサーバーサイドのメトリクスなどの追加情報を含みます。Responseオブジェクトは、データセットを使用した後にクローズする必要があります。


// define parameters. They will be sent to the server along with the request.
Map<String, Object> queryParams = new HashMap<>();
queryParams.put("param1", 2);

try (QueryResponse response =
        client.query("SELECT * FROM " + table + " WHERE col1 >= {param1:UInt32}", queryParams, new QuerySettings()).get()) {

    // Create a reader to access the data in a convenient way
    ClickHouseBinaryFormatReader reader = client.newBinaryFormatReader(response);

    while (reader.hasNext()) {
        reader.next(); // Read the next record from stream and parse it

        // reading data
    }

} catch (Exception e) {
    log.error("Failed to read data", e);
}

queryAll(String sqlQuery)

RowBinaryWithNamesAndTypes フォーマットでデータをクエリします。結果をコレクションとして返します。読み取りパフォーマンスはリーダーと同等ですが、データセット全体を保持するためにより多くのメモリが必要になります。

シグネチャ

List<GenericRecord> queryAll(String sqlQuery)

パラメーター

sqlQuery - サーバーからデータをクエリするためのSQL式。

戻り値

結果データに行形式でアクセスできる GenericRecord オブジェクトのリストで表される、完全なデータセット。

try {
    log.info("Reading whole table and process record by record");
    final String sql = "select * from " + TABLE_NAME + " where title <> ''";

    // Read whole result set and process it record by record
    client.queryAll(sql).forEach(row -> {
        double id = row.getDouble("id");
        String title = row.getString("title");
        String url = row.getString("url");

        log.info("id: {}, title: {}, url: {}", id, title, url);
    });
} catch (Exception e) {
    log.error("Failed to read data", e);
}

QuerySettings

クエリ操作の設定オプション。

設定方法

メソッド 説明
setQueryId(String queryId) 操作に割り当てるクエリ ID を設定します。
setFormat(ClickHouseFormat format) レスポンスのフォーマットを設定します。完全な一覧は RowBinaryWithNamesAndTypes を参照してください。
setMaxExecutionTime(Integer maxExecutionTime) サーバー上での操作の実行時間を設定します。読み取りタイムアウトには影響しません。
waitEndOfQuery(Boolean waitEndOfQuery) レスポンスを送信する前にクエリが終了するまで待機するよう、サーバーに要求します。
setUseServerTimeZone(Boolean useServerTimeZone) サーバーのタイムゾーン (クライアント設定を参照) を使用して、操作結果の日付/時刻型を解析します。既定値は false です。
setUseTimeZone(String timeZone) サーバーに、時刻変換で timeZone を使用するよう要求します。session_timezoneを参照してください。
serverSetting(String name, String value) 操作に対する個別のサーバー設定を行います。
serverSetting(String name, Collection values) 操作に対して、個別のサーバー設定に複数の値を設定します。コレクションの各項目は String 値である必要があります。
setDBRoles(Collection dbRoles) 操作の実行前に設定する DB ロールを指定します。コレクションの項目は String 値である必要があります。
setOption(String option, Object value) 構成オプションを生の形式で設定します。これはサーバー設定ではありません。

QueryResponse

クエリ実行の結果を保持するレスポンスオブジェクトです。クライアントがサーバーからレスポンスを受け取った場合にのみ使用できます。

メソッド 説明
ClickHouseFormat getFormat() レスポンス内のデータがエンコードされているフォーマットを返します。
InputStream getInputStream() 指定したフォーマットのデータの非圧縮バイトストリームを返します。
OperationMetrics getMetrics() 操作メトリクスを含むオブジェクトを返します。
String getQueryId() アプリケーションによってその操作に割り当てられたクエリ ID を返します (操作設定または server により割り当て) 。
TimeZone getTimeZone() レスポンス内の Date/DateTime types を処理する際に使用するタイムゾーンを返します。

  • サンプルコードはリポジトリで公開されています
  • Spring Service のリファレンス 実装

共通API

getTableSchema(String table)

table のテーブルスキーマを取得します。

シグネチャ

TableSchema getTableSchema(String table)
TableSchema getTableSchema(String table, String database)

パラメーター

table - スキーマデータを取得する対象のテーブル名。

database - ターゲットテーブルが定義されているデータベース。

戻り値

テーブルのカラム一覧を含む TableSchema オブジェクトを返します。

getTableSchemaFromQuery(String sql)

SQLステートメントからスキーマを取得します。

シグネチャ

TableSchema getTableSchemaFromQuery(String sql)

パラメーター

sql - スキーマが返される "SELECT" SQL ステートメント。

戻り値

sql 式に対応するカラムを含む TableSchema オブジェクトを返します。

TableSchema

register(Class<?> clazz, TableSchema schema)

schema を使用してデータの書き込み・読み込みを行う Java クラス向けに、シリアライゼーションおよびデシリアライゼーションのレイヤーをコンパイルします。このメソッドは、getter/setter のペアと対応するカラムに対して、シリアライザーとデシリアライザーを生成します。 カラムの照合は、メソッド名からカラム名を抽出することで行われます。たとえば、getFirstName はカラム first_name または firstname に対応します。

シグネチャ

void register(Class<?> clazz, TableSchema schema)

パラメーター

clazz - データの読み書きに使用するPOJOを表すクラス。

schema - POJOプロパティとの照合に使用するデータスキーマ。

client.register(ArticleViewEvent.class, client.getTableSchema(TABLE_NAME));

使用例

完全なサンプルコードは、リポジトリの 'example` フォルダ に保存されています:

  • client-v2 - 主なサンプル一式。
  • demo-service - Spring Boot アプリケーションでクライアントを使用する方法を示す例。
  • demo-kotlin-service - Ktor (Kotlin) アプリケーションでクライアントを使用する方法を示す例。

データの読み取り

データを読み取る一般的な方法は2つあります。

  • データを含む InputStream を持つ低レベルの QueryResponse オブジェクトを返す query() メソッド。通常はストリーミング読み取りのために ClickHouseBinaryFormatReader と組み合わせて使用されますが、 ほかのカスタムリーダー実装でも使用できます。QueryResponse では、結果セットのメタデータとメトリクスにもアクセスできます。
  • queryAll() メソッドを使用し、各行に簡単にアクセスできるように GenericRecord を利用します。この場合、結果セット全体がメモリに読み込まれます。
  • queryRecords() メソッドは com.clickhouse.client.api.query.Records を返します。これは GenericRecord オブジェクトのイテレータです。このメソッドはストリーミング方式を採用しており (データはメモリに読み込まれません) 、GenericRecord を使用してデータにアクセスします。

注意: ストリーミング方式では、データがネットワークストリームから直接読み取られるため、読み取りが遅いとサーバーの書き込みタイムアウトが発生する可能性があります。十分な読み取り速度を確保してください。

配列の読み取り

ClickHouseBinaryFormatReader のメソッド

  • getList(...) - 任意の Array(...)List<T> として読み取ります。柔軟な型付き読み取りの標準的な選択肢です。ネストした配列にも対応しています。
  • getByteArray(...), getShortArray(...), getIntArray(...), getLongArray(...), getFloatArray(...), getDoubleArray(...), getBooleanArray(...) - プリミティブ互換の値で構成される1次元配列に最適です。
  • getStringArray(...) - Array(String) 用 (および名前で表される enum の値) 。
  • getObjectArray(...) - ネストされた配列を含む、あらゆる Array(...) の要素型に対応する汎用オプションです。Nullable な値を含む配列や、ネストされた配列を読み取る際に使用します。

すべてのメソッドに対して、索引ベースおよび名前ベースのオーバーロードが利用可能です。索引は1始まりです。索引ベースはカラムへ直接アクセスします。 名前ベースのメソッドは、呼び出しのたびに索引のルックアップが必要です。

try (QueryResponse response = client.query("SELECT * FROM my_table").get()) {
    ClickHouseBinaryFormatReader reader = client.newBinaryFormatReader(response);
    while (reader.next() != null) {

        Object[] uint64 = reader.getObjectArray("uint64_arr"); // Array(UInt64) -> BigInteger[]
        Object[] arr2d = reader.getObjectArray("arr2d");       // Array(Array(Int64)) -> Object[]

        // nested arrays are returned as nested Object[]:
        Object[] firstInner = (Object[]) arr2d[0];
        Long firstValue = (Long) firstInner[0];
    }
}

GenericRecord メソッド

  • getList(...) - 任意の Array(...)List<T> として読み取ります。柔軟な型付き読み取りの標準的な選択肢です。ネストした配列にも対応しています。
  • getByteArray(...), getShortArray(...), getIntArray(...), getLongArray(...), getFloatArray(...), getDoubleArray(...), getBooleanArray(...) - プリミティブ互換の値で構成される1次元配列に最適です。
  • getStringArray(...) - Array(String) 用 (および名前で表される enum の値) 。
  • getObjectArray(...) - ネストされた配列を含む、あらゆる Array(...) の要素型に対応する汎用オプションです。Nullable な値を含む配列や、ネストされた配列を読み取る際に使用します。

すべてのメソッドに対して、索引ベースおよび名前ベースのオーバーロードが利用可能です。索引は1始まりです。索引ベースはカラムへ直接アクセスします。 名前ベースのメソッドは、呼び出しのたびに索引のルックアップが必要です。

try (QueryResponse response = client.query("SELECT * FROM my_table").get()) {
    List<GenericRecord> rows = client.queryAll(
        "SELECT int_arr, arr2d_nullable FROM test_arrays ORDER BY id");

    for (GenericRecord row : rows) {
        Object[] intArr = row.getObjectArray("int_arr");                 // Array(Int32) -> Integer[]
        Object[] arr2d = row.getObjectArray("arr2d_nullable");           // Array(Array(Nullable(Int32)))

        Object[] inner = (Object[]) arr2d[0];
        Object maybeNull = inner[1]; // may be null
    }
}

移行ガイド

旧クライアント (V1) ではcom.clickhouse.client.ClickHouseClient#builderを起点として使用していました。新クライアント (V2) ではcom.clickhouse.client.api.Client.Builderを用いた同様のパターンを採用しています。主な相違点は以下のとおりです:

  • 実装の取得に service loader は使用されません。com.clickhouse.client.api.Client は、将来的にさまざまな実装に対応するためのファサードクラスです。
  • 設定の定義元が少なくなりました。1 つはビルダーに渡され、もう 1 つは操作設定 (QuerySettingsInsertSettings) にあります。以前のバージョンではノードごとの設定があり、場合によっては 環境変数を読み込んでいました。

設定パラメーターの一致

V1にはconfigurationに関連するenumクラスが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 をすべてのクライアント設定オプションを網羅する単一の Dictionary として使用します。また、すべての設定パラメータ名が列挙された com.clickhouse.client.api.ClientConfigProperties も用意されています。

以下の表に、新しいクライアントでサポートされている旧オプションとその新しい意味を示します。

凡例: ✔ = サポート対象、✗ = 非対応

V1の設定 V2 Builderメソッド 備考
ClickHouseDefaults#HOST Client.Builder#addEndpoint
ClickHouseDefaults#PROTOCOL V2 では HTTP のみサポート
ClickHouseDefaults#DATABASE
ClickHouseClientOption#DATABASE
Client.Builder#setDefaultDatabase
ClickHouseDefaults#USER Client.Builder#setUsername
ClickHouseDefaults#PASSWORD Client.Builder#setPassword
ClickHouseClientOption#CONNECTION_TIMEOUT Client.Builder#setConnectTimeout
ClickHouseClientOption#CONNECTION_TTL Client.Builder#setConnectionTTL
ClickHouseHttpOption#MAX_OPEN_CONNECTIONS Client.Builder#setMaxConnections
ClickHouseHttpOption#KEEP_ALIVE
ClickHouseHttpOption#KEEP_ALIVE_TIMEOUT
Client.Builder#setKeepAliveTimeout
ClickHouseHttpOption#CONNECTION_REUSE_STRATEGY Client.Builder#setConnectionReuseStrategy
ClickHouseHttpOption#USE_BASIC_AUTHENTICATION Client.Builder#useHTTPBasicAuth

主な相違点

  • 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フォーマットのデータを挿入します。

InputStream inData = getInData();
ClickHouseRequest.Mutation request = client.read(server)
        .write()
        .table(tableName)
        .format(ClickHouseFormat.TSV);
ClickHouseConfig config = request.getConfig();
CompletableFuture<ClickHouseResponse> future;
try (ClickHousePipedOutputStream requestBody = ClickHouseDataStreamFactory.getInstance()
        .createPipedOutputStream(config)) {
    // start the worker thread which transfer data from the input into ClickHouse
    future = request.data(requestBody.getInputStream()).execute();

    // Copy data from inData stream to requestBody stream

    // We need to close the stream before getting a response
    requestBody.close();

    try (ClickHouseResponse response = future.get()) {
        ClickHouseResponseSummary summary = response.getSummary();
        Assert.assertEquals(summary.getWrittenRows(), numRows, "Num of written rows");
    }
}

V2でTSVフォーマットのデータを挿入する。

InputStream inData = getInData();
InsertSettings settings = new InsertSettings().setInputStreamCopyBufferSize(8198 * 2); // set copy buffer size
try (InsertResponse response = client.insert(tableName, inData, ClickHouseFormat.TSV, settings).get(30, TimeUnit.SECONDS)) {

  // Insert is complete at this point

} catch (Exception e) {
 // Handle exception
}
  • 呼び出すメソッドは1つだけです。追加のリクエストオブジェクトを作成する必要はありません。
  • すべてのデータのコピーが完了すると、リクエストボディのストリームは自動的に閉じられます。
  • 新しい低レベル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)メソッドを使用して、レコードのコレクションとして読み取ることができます。これにより、データはメモリに読み込まれ、connection は解放されます。追加の処理は必要ありません。GenericRecordを使うとデータにアクセスでき、いくつかの変換も行えます。
Collection<GenericRecord> records = client.queryAll("SELECT * FROM table");
for (GenericRecord record : records) {
    int rowId = record.getInteger("rowID");
    String name = record.getString("name");
    LocalDateTime ts = record.getLocalDateTime("ts");
}

DBサーバーとそのプロトコルを介して通信するためのJavaクライアントライブラリです。現在の実装ではHTTPインターフェイスのみをサポートしています。このライブラリはサーバーへリクエストを送信するための独自のAPIを提供します。

Setup

<!-- https://mvnrepository.com/artifact/com.clickhouse/clickhouse-http-client -->
<dependency>
    <groupId>com.clickhouse</groupId>
    <artifactId>clickhouse-http-client</artifactId>
    <version>0.7.2</version>
</dependency>

バージョン 0.5.0 以降、ドライバーは新しいクライアント HTTP ライブラリを使用するようになりました。このライブラリを依存関係に追加する必要があります。

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 -->
<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.3.1</version>
</dependency>

初期化

接続 URL の形式: protocol://host[:port][/database][?param[=value][&param[=value]][#tag[,tag]]、例:

  • http://localhost:8443?ssl=true&sslmode=NONE
  • https://(https://explorer@play.clickhouse.com:443

単一ノードへの接続:

ClickHouseNode server = ClickHouseNode.of("http://localhost:8123/default?compress=0");

複数のノードを持つクラスターに接続する:

ClickHouseNodes servers = ClickHouseNodes.of(
    "jdbc:ch:http://server1.domain,server2.domain,server3.domain/my_db"
    + "?load_balancing_policy=random&health_check_interval=5000&failover=2");

クエリ API

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
     ClickHouseResponse response = client.read(servers)
        .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
        .query("select * from numbers limit :limit")
        .params(1000)
        .executeAndWait()) {
            ClickHouseResponseSummary summary = response.getSummary();
            long totalRows = summary.getTotalRowsToRead();
}

ストリーミングクエリAPI

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
     ClickHouseResponse response = client.read(servers)
        .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
        .query("select * from numbers limit :limit")
        .params(1000)
        .executeAndWait()) {
            for (ClickHouseRecord r : response.records()) {
            int num = r.getValue(0).asInteger();
            // 型変換
            String str = r.getValue(0).asString();
            LocalDate date = r.getValue(0).asDate();
        }
}

リポジトリ内の完全なコード例を参照してください。

Insert API

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
     ClickHouseResponse response = client.read(servers).write()
        .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
        .query("insert into my_table select c2, c3 from input('c1 UInt8, c2 String, c3 Int32')")
        .data(myInputStream) // `myInputStream` は RowBinary フォーマットのデータソース
        .executeAndWait()) {
            ClickHouseResponseSummary summary = response.getSummary();
            summary.getWrittenRows();
}

repo にある完全なコード例を参照してください。

RowBinaryエンコーディング

RowBinary フォーマットの詳細については、こちらのページを参照してください。

コードの例を参照してください。

機能

圧縮

クライアントはデフォルトで LZ4 圧縮を使用します。これには次の依存関係が必要です。

<!-- https://mvnrepository.com/artifact/org.lz4/lz4-java -->
<dependency>
    <groupId>org.lz4</groupId>
    <artifactId>lz4-java</artifactId>
    <version>1.8.0</version>
</dependency>

接続URLにcompress_algorithm=gzipを設定することで、代わりにgzipを使用することができます。

または、いくつかの方法で圧縮を無効にすることもできます。

  1. 接続 URL で compress=0 を指定して無効化します: http://localhost:8123/default?compress=0
  2. クライアント設定で無効化します:
ClickHouseClient client = ClickHouseClient.builder()
   .config(new ClickHouseConfig(Map.of(ClickHouseClientOption.COMPRESS, false)))
   .nodeSelector(ClickHouseNodeSelector.of(ClickHouseProtocol.HTTP))
   .build();

さまざまな圧縮オプションの詳細については、圧縮ドキュメントを参照してください。

複数のクエリ

同一セッション内でワーカースレッドを使用して複数のクエリを順番に実行する:

CompletableFuture<List<ClickHouseResponseSummary>> future = ClickHouseClient.send(servers.apply(servers.getNodeSelector()),
    "create database if not exists my_base",
    "use my_base",
    "create table if not exists test_table(s String) engine=Memory",
    "insert into test_table values('1')('2')('3')",
    "select * from test_table limit 1",
    "truncate table test_table",
    "drop table if exists test_table");
List<ClickHouseResponseSummary> results = future.get();

名前付きパラメータ

パラメータリスト内の位置に依存せず、名前でパラメータを渡すことができます。この機能は params 関数を使用して利用できます。

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
     ClickHouseResponse response = client.read(servers)
        .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
        .query("select * from my_table where name=:name limit :limit")
        .params("Ben", 1000)
        .executeAndWait()) {
            //...
        }
}

ノードディスカバリー

Java クライアントには、ClickHouse ノードを自動的に検出する機能があります。自動検出はデフォルトで無効です。手動で有効にするには、auto_discoverytrue に設定します。

properties.setProperty("auto_discovery", "true");

または、接続URLで:

jdbc:ch://my-server/system?auto_discovery=true

自動検出が有効な場合、接続URLにすべてのClickHouseノードを指定する必要はありません。URLに指定されたノードはシードとして扱われ、Java クライアントはシステムテーブルおよび/またはclickhouse-keeperやzookeeperから追加のノードを自動的に検出します。

以下のオプションは、自動検出の設定に関するものです:

プロパティ デフォルト 説明
auto_discovery false クライアントがシステムテーブルや clickhouse-keeper/zookeeper からさらにノードを検出するかどうか。
node_discovery_interval 0 ノード検出の間隔 (ミリ秒) 。0 以下の値は一回限りの検出を意味します。
node_discovery_limit 100 一度に検出可能なノードの最大数。値が0以下の場合は、制限なしを意味します。

負荷分散

Java クライアントは、ロードバランシングポリシーに従って、リクエストの送信先となる ClickHouse ノードを選択します。一般に、ロードバランシングポリシーは次の役割を担います。

  1. 管理対象ノードの一覧からノードを取得します。
  2. ノードの状態管理。
  3. 必要に応じて、ノード検出用のバックグラウンドプロセス (自動検出が有効な場合) をスケジュールし、ヘルスチェックを実行します。

ロードバランシングを設定するオプションの一覧を以下に示します:

プロパティ デフォルト 説明
load_balancing_policy "" 負荷分散ポリシーには、次のいずれかを指定できます。
  • firstAlive - リクエストは、管理対象ノードのリスト内で最初に正常なノードに送信されます
  • random - リクエストは、管理対象ノードのリストからランダムに選択されたノードに送信されます
  • roundRobin - リクエストは、管理対象ノードのリスト内の各ノードに順番に送信されます。
  • ClickHouseLoadBalancingPolicy を実装する完全修飾クラス名 - カスタム負荷分散ポリシー
  • 指定しない場合、リクエストは管理対象ノードのリストの先頭ノードに送信されます
    load_balancing_tags "" ノードを絞り込むためのロードバランシングタグ。リクエストは、指定したタグを持つノードにのみ送信されます
    health_check_interval 0 ヘルスチェックの間隔 (ミリ秒) 。値が 0 以下の場合は一回限りになります。
    health_check_method ClickHouseHealthCheckMethod.SELECT_ONE ヘルスチェックの方法。次のいずれかを指定できます:
  • ClickHouseHealthCheckMethod.SELECT_ONE - select 1 クエリでチェック
  • ClickHouseHealthCheckMethod.PING - プロトコル固有のチェックで、通常はこちらの方が高速です
  • node_check_interval 0 ノードチェックの間隔をミリ秒単位で指定します。負の値は 0 として扱われます。前回のチェックから指定した時間が経過している場合に、そのノードの status がチェックされます。
    health_check_intervalnode_check_interval の違いは、health_check_interval オプションはノードのリスト (すべてまたは障害のあるノード) の status をチェックするバックグラウンドジョブをスケジュールするのに対し、node_check_interval は特定のノードについて前回のチェックからどれだけ時間が経過している必要があるかを指定する点です
    check_all_nodes false ヘルスチェックの対象をすべてのノードにするか、障害のあるノードのみにするか。

    フェイルオーバーと再試行

    Java クライアントは、失敗したクエリに対するフェイルオーバーと再試行の動作を設定するための設定オプションを提供します。

    プロパティ デフォルト 説明
    failover 0 リクエストでフェイルオーバーが発生する最大回数。0 または負の値は、フェイルオーバーを行わないことを意味します。フェイルオーバーでは、失敗したリクエストを復旧のために別のノード (負荷分散ポリシーに従う) へ送信します。
    retry 0 リクエストに対して再試行を実行できる最大回数です。ゼロまたは負の値は、再試行しないことを意味します。再試行では、ClickHouse server が NETWORK_ERROR エラーコードを返した場合にのみ、リクエストが同じノードに送信されます
    repeat_on_session_lock true セッションがロックされている場合に、タイムアウトするまで (session_timeout または connect_timeout に従って) 実行を繰り返すかどうか。ClickHouse server が SESSION_IS_LOCKED エラーコードを返した場合、失敗したリクエストが再実行されます

    カスタムHTTPヘッダーを追加する

    Java クライアントは、リクエストにカスタム HTTP ヘッダーを追加する場合に HTTP/S トランスポートレイヤーをサポートしています。 custom&#95;http&#95;headers プロパティを使用してください。ヘッダーは , 区切りで指定し、ヘッダーのキーと値は = で区切ります。

    Java クライアント対応

    options.put("custom_http_headers", "X-ClickHouse-Quota=test, X-ClickHouse-Test=test");

    JDBCドライバー

    properties.setProperty("custom_http_headers", "X-ClickHouse-Quota=test, X-ClickHouse-Test=test");
    Navigation