メインコンテンツへスキップ
clickhouse-jdbc は、最新の Java クライアントを用いて標準的な JDBC インターフェイスを実装しています。 パフォーマンスや直接アクセスが重要な場合は、最新の Java クライアントを直接使用することを推奨します。

環境要件

Setup

アプリケーション内でJDBCドライバーを使用しており、jarをクラスパスに追加する必要がある場合は、以下からjarをダウンロードしてください:

設定

ドライバークラス: com.clickhouse.jdbc.ClickHouseDriver
com.clickhouse.jdbc.ClickHouseDriver は、新旧の JDBC 実装に対するファサードクラスです。デフォルトでは、新しい JDBC 実装が使用されます。 古い JDBC 実装を使用するには、clickhouse.jdbc.v1 システムプロパティを true に設定します。このプロパティは、Driver クラスを呼び出す前に設定する必要があります。バージョンを切り替える別の方法として、各バージョンの Driver クラスを直接使用することもできます。
  • com.clickhouse.jdbc.Driver は新しい JDBC 実装 (V2) です。
  • com.clickhouse.jdbc.DriverV1 は古い JDBC 実装 (V1) です。
URL 構文: jdbc:(ch|clickhouse)[:<protocol>]://endpoint[:port][/<database>][?param1=value1&param2=value2][#tag1,tag2,...]、例:
  • jdbc:clickhouse:http://localhost:8123
  • jdbc:clickhouse:https://localhost:8443?ssl=true
URLの構文については、以下の点に注意してください。
  • URL には 1 つのエンドポイントのみ指定できます
  • デフォルトの ‘HTTP’ 以外を使用する場合は、プロトコルを指定する必要があります
  • ポートは、デフォルトの ‘8123’ 以外を使用する場合に指定する必要があります
  • ドライバーはポート番号からプロトコルを推測しないため、明示的に指定する必要があります
  • プロトコルが指定されている場合、ssl パラメータは不要です。

接続プロパティ

主な設定パラメーターは Java クライアント で定義されています。これらはそのままドライバーに渡してください。ドライバー固有のプロパティでクライアント設定に含まれないものは、以下に一覧を示します。ドライバーのプロパティ:
サーバー設定すべてのサーバー設定には、clickhouse_setting_ プレフィックスを付ける必要があります (クライアントの設定と同様です) 。
設定例:
これは以下のJDBC URLと同等です:
注意: JDBC URLやプロパティをURLエンコードする必要はありません。自動的にエンコードされます。読み取り専用プロファイル読み取り専用プロファイルとの問題を避けるため、接続プロパティにデフォルト設定を意図的に追加していません。 ただし、フォーマット設定を渡す必要があるユーザー (例: JSON を String として読み取る場合) には、readonly=2 プロファイルの使用を推奨します。 読み取り専用プロファイルの詳細については、こちらを参照してください。

クライアント識別

リクエストを発行したアプリケーションを識別する方法は2つあります。接続プロパティで com.clickhouse.client.api.ClientConfigProperties#CLIENT_NAME を設定するか、java.sql.Connection#setClientInfo(String name, String value) メソッドを使用します。
showLineNumbers
showLineNumbers
どちらの方法でも、クエリログの http_user_agent の値は次のようになります:
注意: client_name プロパティには app_name/version フォーマットの使用を推奨します。クエリログでアプリケーションを識別しやすくなるためです。

オペレーションの識別

JDBCドライバーは操作ごとに query_id を生成します (現在はサーバーの例外に含まれています) 。操作に対して log_comment を設定するには、com.clickhouse.jdbc.StatementImpl#getLocalSettings メソッドを使用します。これには、Statement または PreparedStatement を事前に com.clickhouse.jdbc.StatementImpl にキャストする必要があります。
showLineNumbers
注意: localSettings はスレッド間で共有されるため、このアプローチはステートメントのシングルスレッド使用時にのみ有効です。

サポートされているデータ型

JDBCドライバーは、基盤となるJava クライアントと同じデータフォーマットをサポートしています。

JDBC 型マッピング

以下のマッピングが適用される対象:
  • ResultSet#getObject(columnIndex) - 対応する Java クラスのオブジェクトを返すメソッドです。(Int8 -> java.lang.Byte, Int16 -> java.lang.Short など)
  • ResultSetMetaData#getColumnType(columnIndex) - メソッドは、対応するJDBC型を返します。(Int8 -> java.lang.Byte, Int16 -> java.lang.Short, など)
マッピングを変更する方法はいくつかあります:
  • ResultSet#getObject(columnIndex, class) - このメソッドは値をclass型に変換しようとします。変換にはいくつか制限があります。詳細は各セクションを参照してください。
数値型
  • 数値型は相互に変換できます。したがって、Int8Float64 として取得でき、逆も同様です。:
    • rs.getObject(1, Float64.class) は、Int8 カラムの値を Float64 として返します。
    • rs.getLong(1) は、Int8 カラムの値を Long として返します。
    • rs.getByte(1) は、Byte に収まる場合、Int16 カラムの値を Byte として返すことができます。
  • より広い型からより狭い型への変換は、データが破損するおそれがあるため推奨されません。
  • Bool 型は数値としても扱われます。
  • すべての数値型は java.lang.String として読み出すことができます。
  • Java の Float.MAX_VALUEFloat として保存すると問題が発生します (https://github.com/ClickHouse/clickhouse-java/issues/809) 。同じ値を Double として保存すれば、この問題は解決します。
文字列型
  • String は、java.lang.String または byte[] としてのみ読み込めます。
  • FixedString はそのまま読み取られ、カラムの長さに合わせてゼロで埋められます。 (たとえば、'John' に対する FixedString(10)'John\0\0\0\0\0\0\0\0\0' として読み取られます。)
列挙型
  • Enum8Enum16 は、デフォルトでは java.lang.String にマッピングされます。
  • Enum 値は、指定された getter メソッドまたは getObject(columnIndex, Integer.class) メソッドを使用して、数値として読み取ることができます。
  • Enum16 は内部的に short にマッピングされ、Enum8 は byte にマッピングされます。データ破損のリスクがあるため、Enum16 を byte として読み取るのは避けてください。
  • Enum の値は、PreparedStatement では文字列または数値として設定できます。
日付/時刻型
  • Date / Time 型は、JDBC との互換性を高めるため、java.sql 型にマッピングされます。ただし、ResultSet#getObject(columnIndex, Class<T>) を使用し、第 2 引数に対応するクラスを指定することで、java.time.LocalDatejava.time.LocalDateTimejava.time.LocalTime を取得することもできます。
    • rs.getObject(1, java.time.LocalDate.class) は、Date カラムの値を java.time.LocalDate として返します。
    • rs.getObject(1, java.time.LocalDateTime.class) は、DateTime カラムの値を java.time.LocalDateTime として返します。
    • rs.getObject(1, java.time.LocalTime.class) は、Time カラムの値を java.time.LocalTime として返します。
  • Date, Date32, Time, Time64 はサーバーのタイムゾーンの影響を受けません。
  • DateTimeDateTime64 は、サーバーまたはセッションのタイムゾーンの影響を受けます。
  • DateTimeDateTime64 は、getObject(colIndex, ZonedDateTime.class) を使用して ZonedDateTime として取得できます。
ネストされた型
  • JDBC との互換性を確保するため、Array はデフォルトで java.sql.Array にマッピングされます。これは、返される配列値についてより多くの情報を提供するためでもあります。型推論に役立ちます。
  • Array は、元の配列と同じ内容の java.sql.ResultSet を返す getResultSet() メソッドを実装しています。
  • コレクション型を java.lang.String として読み取るべきではありません。この形式はデータの有効な表現方法ではないためです (例: 配列内の文字列値はクォートされません) 。
  • MapOTHER に対応付けられます。値は getObject(columnIndex, Class<T>) メソッドでしか読み取れないためです。
    • Map には名前付きカラムがないため、java.sql.Struct ではありません。
  • Tuple は異なる型を含めることができ、List は使用できないため、Object[] にマップされます。
  • Tuple は、getObject(columnIndex, Array.class) メソッドを使用して Array として読み取れます。この場合、Array#baseTypeNameTuple のカラム定義を返します。
Array要素型のメタデータArray.getBaseTypeName() は ClickHouse の要素型名を返し、Array.getBaseType() は JDBC 型コードを返します。 JDBC V2 は、V1 が省略するラッパー型や型パラメーターを含む完全な型シグネチャを保持します。配列の一般的なマッピングルールは以下のとおりです:上記のルールに関する注意事項:
  • ラッパー型 (Nullable, LowCardinality) は getBaseTypeName() では保持されますが、getBaseType() は内部の型の JDBC コードを返します。
  • ネストされた配列はメタデータ内でフラット化されます。getBaseTypeName() が返すのは直接の子要素ではなく、最も内側にある非配列要素の型です。
  • パラメーター化された型 (FixedString(N)、完全な Enum/Tuple 定義) は、getBaseTypeName() でパラメーターが保持されます。
例:
  • V2 では、getBaseTypeName() はラッパー型 (Nullable, LowCardinality) や型パラメーター (FixedString(8)、完全な Enum および Tuple の定義) を含む完全な型シグネチャを保持します。V1 ではこれらが取り除かれ、基本型名のみが返されます。
  • ClickHouse のタプルは名前付きフィールドを持ち、java.sql.Struct ではそれをサポートしていないため、Tuple 配列は V2 では STRUCT (2002) ではなく OTHER (1111) を使用します。
  • UUID 配列は、スカラーの UUID マッピングに合わせて、V2 では OTHER (1111) を使用します。
  • Enum 値は VARCHAR にマッピングされます。enum メンバーは、基になる数値エンコーディングに関係なく、文字列名で識別されるためです。
Arrayの書き込みjava.sql.Connection#createArrayOf を使用して java.sql.Array オブジェクトをインスタンス化します。このオブジェクトは、異なるデータベース間でのArray処理を統一するために設計されています。 Arrayファクトリメソッドにconfigurationを渡すには、Connectionが必要です。このメソッドは2つの引数を受け取ります:
  • typeName - 配列要素の型名。例: Array(Int32) -> "Int32"
  • elements - 配列の実際の要素。たとえば [[1, 2, 3], [4, 5, 6]] -> new Integer[][] {{1, 2, 3}, {4, 5, 6}}
TupleはObject[]またはjava.sql.Structとして表現できます (タプルの記述方法については以下を参照してください) 。
Arrayの読み取りResultSet#getArray(columnIndex) を使用して Array オブジェクトを読み取ります。このオブジェクトを使用すると、任意のネスト深度のArrayにアクセスできます。 Array#getResultSet() メソッドを使用すると、配列要素を java.sql.ResultSet として統一的な方法で読み取ることができます。配列要素の正確な型が不明な場合に便利です。
Tupleの書き方Tupleはcom.clickhouse.data.Tupleオブジェクトにマッピングされます。書き込む際は、setObject(columnIndex, tuple)メソッドを呼び出してこのオブジェクトとして渡してください。 移植性を高めるために、java.sql.Structオブジェクトを使用してTupleを書き込むこともできます。
Tuplesの読み込みメソッド getObject(columnIndex)Object[] を返します。Tupleは getObject(columnIndex, Array.class) メソッドを使用して java.sql.Array として読み取ることができます。
Mapの書き込みMap は java.collections.Map オブジェクトとしてのみ書き込み可能です。このデータ型はキー・バリューペアを必要とするためです (java.sql.Struct はキー・バリューペアをサポートしていません) 。
地図の読み方MapはgetObject(columnIndex, Map.class)メソッドを使用することで、java.collections.Mapオブジェクトとして読み取ることができます。
ネストへの書き込みjava.sql.Connection#createStruct を使用して java.sql.Struct オブジェクトをインスタンス化します。このオブジェクトは、異なるデータベース間でネストされた処理を統一するために設計されています。 Struct ファクトリメソッドに設定を渡すには、コネクションが必要です。このメソッドは2つの引数を受け取ります:
  • typeName - ネストされた要素の型名です。たとえば Nested(Tuple(Int32, String)) -> "Nested(Tuple(Int32, String))"
  • elements - 実際にネストされた要素。たとえば、[1, 'test'] -> new Object[] {1, 'test'}
ネストされたデータの読み取りResultSet#getStruct(columnIndex, StructDescriptor) を使用して Nested オブジェクトを読み取ります。このオブジェクトを使用すると、任意のネスト深度のネストにアクセスできます。 Struct#getResultSet() メソッドを使用すると、ネストされた要素を java.sql.ResultSet と同様の統一的な方法で読み取ることができます。ネストされた要素の正確な型が不明な場合に便利です。
Geo TypesNullableとLowCardinalityの型
  • NullableLowCardinality は、ほかの型をラップする特殊な型です。
  • Nullable は、ResultSetMetaData で型名がどのように返されるかに影響します
特殊型
  • UUID は JDBC の標準型ではありません。ただし、JDK には含まれています。デフォルトでは、getObject() メソッドは java.util.UUID を返します。
  • getObject(columnIndex, String.class) メソッドを使用すると、UUIDString として読み書きできます。
  • IPv4IPv6 は JDBC の標準型ではありません。ただし、JDK には含まれています。デフォルトでは、getObject() メソッドは java.net.Inet4Addressjava.net.Inet6Address を返します。
  • IPv4IPv6 は、getObject(columnIndex, String.class) メソッドを使うと、String として読み書きできます。
JSON型JSON 型はデフォルトで Map<String, Object> にマッピングされます。キーは JSON オブジェクトのキー、値は JSON オブジェクトの値です。 例:
以下にマッピングされます:
接続プロパティにサーバー設定 jdbc_read_json_as_string=true を渡すことで、JSONをStringとして読み取るより便利な方法があります。 これにより、ドライバーはJSON値をStringとして返すようになり、任意のJSONライブラリを使用して解析できます。
ClickHouse バージョン 25.8 以降、数値はデフォルトでクォートされなくなりました。それより古いバージョンでは、サーバー設定を接続プロパティに渡すことでクォートを無効にできます:

日付、時刻、タイムゾーンの処理

日付/時刻およびタイムスタンプの処理におけるドライバーの動作と注意点については、Date/Time Guideを参照してください。

接続の作成

認証情報と設定の指定

showLineNumbers

シンプルなステートメント

showLineNumbers

インサート

showLineNumbers

HikariCP

showLineNumbers

詳細情報

詳細については、GitHub リポジトリおよび Java クライアントのドキュメントを参照してください。

トラブルシューティング

ロギング

ドライバーはロギングにslf4jを使用し、classpath上で最初に見つかった実装を使用します。

大規模インサート時のJDBCタイムアウトの解消

ClickHouseで実行時間の長い大規模なinsertを実行する際、次のようなJDBCタイムアウトエラーが発生する場合があります:
これらのエラーはデータの挿入プロセスを妨げ、システムの安定性に影響を及ぼす可能性があります。この問題に対処するには、クライアントのOSでいくつかのタイムアウト設定を調整する必要があります。

Mac OS

Mac OS では、以下の設定を調整することで問題を解決できます:
  • net.inet.tcp.keepidle: 60000
  • net.inet.tcp.keepintvl: 45000
  • net.inet.tcp.keepinit: 45000
  • net.inet.tcp.keepcnt: 8
  • net.inet.tcp.always_keepalive: 1

Linux

Linuxでは、同等の設定だけでは問題が解決しない場合があります。Linuxのソケットキープアライブ設定の処理方法が異なるため、追加の手順が必要です。以下の手順に従ってください。
  1. /etc/sysctl.conf または関連する設定ファイルで、以下の Linux カーネルパラメーターを調整します。
  • net.inet.tcp.keepidle: 60000
  • net.inet.tcp.keepintvl: 45000
  • net.inet.tcp.keepinit: 45000
  • net.inet.tcp.keepcnt: 8
  • net.inet.tcp.always_keepalive: 1
  • net.ipv4.tcp_keepalive_intvl: 75
  • net.ipv4.tcp_keepalive_probes: 9
  • net.ipv4.tcp_keepalive_time: 60 (この値は、デフォルトの300秒から引き下げることを検討してもよいでしょう)
  1. カーネルパラメータを変更した後、次のコマンドを実行して変更を反映してください。
これらの設定を行った後、クライアントがソケット上でKeep Aliveオプションを有効にしていることを確認してください。

移行ガイド

主な変更点

  • JDBC V2 は、より軽量な実装となっており、一部の機能が削除されています。
    • ストリーミングデータはJDBC仕様やJavaに含まれていないため、JDBC V2ではサポートされていません。
  • JDBC V2 では明示的な設定が必要です。フェイルオーバーのデフォルト設定はありません。
    • URLにはプロトコルを指定する必要があります。ポート番号による暗黙的なプロトコル判別は行われません。

設定の変更

enumは2つのみです:
  • com.clickhouse.jdbc.DriverProperties - ドライバー固有の設定プロパティ。
  • com.clickhouse.client.api.ClientConfigProperties - クライアント設定のプロパティです。クライアント設定の 変更点については、Java クライアントのドキュメントで説明しています。
接続プロパティは以下の方法で解析されます:
  • まず URL からプロパティが解析されます。それらは他のすべてのプロパティを上書きします。
  • ドライバーのプロパティはクライアントには渡されません。
  • エンドポイント (ホスト、ポート、プロトコル) はURLから抽出されます。
例:

データ型の変更

数値型
  • 最大の違いは、移植性を高めるために、符号なし型がJavaの型にマッピングされている点です。
文字列型
  • FixedString は、どちらのバージョンでもそのまま読み取られます。たとえば、'John' に対する FixedString(10)'John\0\0\0\0\0\0\0\0\0' として読み取られます。
  • PreparedStatement#setBytes を使用すると、unhex('<hex_string>') に変換され、その後 String として読み込まれます。
  • StringはUTF-8でエンコードされて保存されます。
日付/時刻型
  • TimeTime64 は、V2 でのみ新しい型としてサポートされています。
  • DateTimeDateTime64 は、JDBC との互換性を高めるため、java.sql.Timestamp にマッピングされます。
列挙型ネストされた型
  • V2 では、JDBC との互換性を保つため、Array はデフォルトで java.sql.Array にマッピングされます。これは、返される配列値に関する情報をより多く提供するためでもあります。型推論に役立ちます。
  • V2では、Array は元の配列と同じ内容を持つ java.sql.ResultSet を返す getResultSet() メソッドを実装しています。
  • V1 では MapSTRUCT を使用しますが、返されるのは常に java.util.Map オブジェクトです。V2 では、MapJAVA_OBJECT にマッピングすることでこの問題を修正しています。
  • V1 では TupleSTRUCT を使用しますが、返り値は常に List<Object> オブジェクトです。V2 では TupleOTHER にマップされ、デフォルトでは Object[] が返されます。
  • V2 では、タプルを書き込むための com.clickhouse.data.Tuple#Tuple が導入されました。これにより、値がタプルなのか配列なのかを簡単に見分けられます。
  • PreparedStatement#setBytesResultSet#getBytes は、コレクション型では使用できません。これらのメソッドは、バイナリ文字列を扱うように設計されています。
  • 通常、Array型の書き込みと読み取りには java.sql.Array を使用します。JDBCドライバーはこれを完全にサポートしています。
  • V2 では NestedArray にマッピングされ、タプルの配列として扱われます。
  • V2 は java.sql.Struct を部分的にサポートしています。これは Array 型と非常によく似ていますが、キー・バリューのペアはサポートしていません。StructTuple の値を書き込むために使用できます。
Geo TypesNullableとLowCardinalityの型
  • NullableLowCardinality は、他の型を包む特殊な型です。
  • V2では、これらの型に変更はありません。
特殊型
  • V1 では UUIDVARCHAR を使用していますが、常に java.util.UUID オブジェクトを返します。V2 では、UUIDOTHER にマッピングすることでこの問題を修正し、java.util.UUID オブジェクトを返します。
  • V1 では IPv4IPv6VARCHAR を使用していますが、返されるのは常に java.net.Inet4Address および java.net.Inet6Address オブジェクトです。V2 では、IPv4IPv6OTHER にマッピングすることでこの問題を修正し、java.net.Inet4Address および java.net.Inet6Address オブジェクトを返すようになりました。
  • DynamicVariant は V2 で導入された新しい型です。V1 ではサポートされていません。
  • JSONDynamic 型をベースにしています。そのため、V2 でのみサポートされます。
  • IPv4 および IPv6 の値は、getBytes(columnIndex) メソッドを使用して byte[] として読み取ることもできます。ただし、これらの型については専用のクラスを使用することを推奨します。
  • V2 は、変換が InetAddress クラスでより適切に実装されているため、IP アドレスを数値として読み取ることには対応していません。

データベースメタデータの変更

  • V2 では、データベースの名称には Schema のみを使用します。Catalog は今後のために予約されています。
  • V2 では、DatabaseMetaData.supportsTransactions()DatabaseMetaData.supportsSavepoints()false を返します。これは今後変更される予定です。
  • DatabaseMetaData.getTypeInfo() では、LITERAL_PREFIX および LITERAL_SUFFIX カラムは、プレフィックスや接尾辞が想定されないデータ型 (たとえば数値型) に対して null を返すようになりました。 V1 では、これらのカラムはそのような型に対して非 null 値を返していました。これらのカラムは、データ型に応じてリテラル値を適切にクォートできるよう、SQL クエリの生成時に使用する必要があります。
最終更新日 2026年6月25日