JDBC ドライバー
clickhouse-jdbcは最新のJavaクライアントを使用して標準的なJDBCインターフェースを実装しています。
パフォーマンスや直接アクセスが重要な場合は、最新のJavaクライアントを直接使用することを推奨します。
環境要件
- OpenJDK バージョン >= 8
セットアップ
- Maven
- Gradle (Kotlin)
- Gradle
クラスパスにjarを追加する必要があるアプリケーションでJDBCドライバーを使用している場合は、以下からjarをダウンロードしてクラスパスに追加してください:
- Maven Central から jar をダウンロードし、クラスパスに追加します
- バージョン
0.9.4以降は、アーティファクト https://mvnrepository.com/artifact/com.clickhouse/clickhouse-jdbc-all が利用可能です。 - すべての shaded 依存関係を含む JAR を取得するには、クラスファイア
allを指定してください。
- バージョン
- または公式リポジトリのこちらからダウンロードできます
設定
ドライバークラス: com.clickhouse.jdbc.ClickHouseDriver
com.clickhouse.jdbc.ClickHouseDriverは、新旧両方のJDBC実装のためのファサードクラスです。デフォルトでは新しいJDBC実装が使用されます。
システムプロパティ clickhouse.jdbc.v1 を true に設定することで、古いJDBC実装を使用できます。このプロパティはDriverクラスを呼び出す前に設定する必要があります。
バージョンを切り替える別の方法として、各バージョンの Driver クラスを直接使用することもできます。
com.clickhouse.jdbc.Driverは新しい JDBC 実装 (V2) です。com.clickhouse.jdbc.DriverV1は旧バージョンの JDBC 実装 (V1) です。
URL構文: jdbc:(ch|clickhouse)[:<protocol>]://endpoint[:port][/<database>][?param1=value1¶m2=value2][#tag1,tag2,...]。例えば:
jdbc:clickhouse:http://localhost:8123jdbc:clickhouse:https://localhost:8443?ssl=true
URL の構文については、次の点に注意してください:
- URL にはエンドポイントを 1 つだけ指定できます
- プロトコルがデフォルトの「HTTP」以外の場合は、明示的に指定する必要があります
- デフォルトの '8123' 以外のポートを使用する場合は、そのポート番号を明示的に指定する必要があります
- ドライバーはポート番号からプロトコルを推測しないため、プロトコルを必ず明示的に指定する必要があります
- プロトコルを明示的に指定している場合は、
sslパラメーターを指定する必要はありません。
接続プロパティ
主要な設定パラメータはJavaクライアントで定義されています。これらはそのままドライバに渡す必要があります。ドライバにはクライアント設定に含まれない独自のプロパティがあり、以下に記載されています。
ドライバープロパティ:
| プロパティ | デフォルト値 | 説明 |
|---|---|---|
disable_frameworks_detection | true | User-Agent を用いたフレームワーク検出を無効にする |
jdbc_ignore_unsupported_values | false | ドライバーの動作に影響しない箇所では SQLFeatureNotSupportedException を抑制します |
clickhouse.jdbc.v1 | false | 新しい JDBC 実装ではなく旧 JDBC 実装を使用する |
default_query_settings | null | クエリ実行時にデフォルトのクエリ設定を渡せるようにする |
jdbc_resultset_auto_close | true | Statement をクローズするときに ResultSet を自動的にクローズします |
beta.row_binary_for_simple_insert | false | RowBinary writer に基づく PreparedStatement 実装を使用します。INSERT INTO ... VALUES クエリでのみ動作します。 |
jdbc_resultset_auto_close | true | Statement をクローズすると ResultSet も自動的にクローズされます |
jdbc_use_max_result_rows | false | サーバープロパティ max_result_rows によって、クエリが返す行数を制限できるようにします。有効にすると、ユーザーが設定したオーバーフローモードを上書きします。詳細は JavaDoc を参照してください。 |
jdbc_sql_parser | JAVACC | 使用する SQL パーサーを設定します。選択肢は ANTLR4, ANTLR4_PARAMS_PARSER, JAVACC です。 |
remember_last_set_roles | true | 接続に対して最後に設定されたロールを保持する。 |
設定例:
これは、次の JDBC URL と同等です:
注記: JDBC URL や接続プロパティを URL エンコードする必要はありません。自動的にエンコードされます。
クライアント識別
リクエストの発信元アプリケーションを識別する方法は2つあります。接続プロパティで com.clickhouse.client.api.ClientConfigProperties#CLIENT_NAME を設定するか、java.sql.Connection#setClientInfo(String name, String value) メソッドを使用します。
どちらの方法でも、クエリログの http_user_agent の値は次のようになります。
操作の識別
JDBCドライバーは各操作ごとに query_id を生成します (現在はサーバー例外に含まれています) 。
操作に対して log_comment を設定するには、com.clickhouse.jdbc.StatementImpl#getLocalSettings メソッドを使用します。これには、
Statement または PreparedStatement を事前に com.clickhouse.jdbc.StatementImpl にキャストする必要があります。
注意: 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型に変換しようとします。変換にはいくつかの制限があります。詳細は各セクションを参照してください。
数値型
| ClickHouse 型 | JDBC 型 | Java クラス |
|---|---|---|
| Int8 | TINYINT | java.lang.Byte |
| Int16 | SMALLINT | java.lang.Short |
| Int32 | INTEGER | java.lang.Integer |
| Int64 | BIGINT | java.lang.Long |
| Int128 | OTHER | java.math.BigInteger |
| Int256 | OTHER | java.math.BigInteger |
| UInt8 | OTHER | java.lang.Short |
| UInt16 | OTHER | java.lang.Integer |
| UInt32 | OTHER | java.lang.Long |
| UInt64 | OTHER | java.math.BigInteger |
| UInt128 | OTHER | java.math.BigInteger |
| UInt256 | OTHER | java.math.BigInteger |
| Float32 | REAL | java.lang.Float |
| Float64 | DOUBLE | java.lang.Double |
| Decimal32 | DECIMAL | java.math.BigDecimal |
| Decimal64 | DECIMAL | java.math.BigDecimal |
| Decimal128 | DECIMAL | java.math.BigDecimal |
| Decimal256 | DECIMAL | java.math.BigDecimal |
| Bool | BOOLEAN | java.lang.Boolean |
- 数値型同士は相互に変換可能です。たとえば、
Int8をFloat64として取得したり、その逆にFloat64をInt8として取得することも可能です。rs.getObject(1, Float64.class)は、Int8カラムの値をFloat64型として返します。rs.getLong(1)は、Int8カラムの値をLong型として返します。rs.getByte(1)は、Int16カラムの値がByteの範囲に収まる場合、その値をByte型として返します。
- より広い型からより狭い型への変換は、データ破損のリスクがあるため推奨されません。
Bool型は数値型としても扱われます。- すべての数値型は
java.lang.Stringとして取得できます。 - Java の
Float.MAX_VALUEをFloatとして保存すると問題が発生します (https://github.com/ClickHouse/clickhouse-java/issues/809)。同じ値をDoubleとして保存すると、この問題は解決します。
文字列型
| ClickHouse 型 | JDBC 型 | Java クラス |
|---|---|---|
| String | VARCHAR | java.lang.String |
| FixedString | VARCHAR | java.lang.String |
Stringはjava.lang.Stringまたはbyte[]としてのみ読み取れます。FixedStringは値をそのまま読み取り、カラムの長さに達するまで末尾をゼロバイト (\0) で埋めます。 (たとえば、FixedString(10)で'John'を指定した場合、'John\0\0\0\0\0\0\0\0\0'として読み取られます。)
Enum型
| ClickHouse 型 | JDBC 型 | Java クラス |
|---|---|---|
| Enum8 | OTHER | java.lang.String |
| Enum16 | OTHER | java.lang.String |
Enum8およびEnum16は、デフォルトでjava.lang.Stringにマッピングされます。- Enum の値は、専用の getter メソッドまたは
getObject(columnIndex, Integer.class)メソッドを使用して数値として読み取ることができます。 Enum16は内部的にはshort型に、Enum8はbyte型にマッピングされます。データ破損のリスクがあるため、Enum16をbyte型として読み出すことは避けてください。- Enum の値は、
PreparedStatementで文字列または数値として設定できます。
日付/時刻型
| ClickHouse 型 | JDBC 型 | Java クラス |
|---|---|---|
| Date | DATE | java.sql.Date |
| Date32 | DATE | java.sql.Date |
| DateTime | TIMESTAMP | java.sql.Timestamp |
| DateTime64 | TIMESTAMP | java.sql.Timestamp |
| Time | TIME | java.sql.Time |
| Time64 | TIME | java.sql.Time |
- Date / Time 型は、JDBC との互換性を高めるために
java.sql型にマッピングされます。ただし、ResultSet#getObject(columnIndex, Class<T>)の第 2 引数として対応するクラスを指定することで、java.time.LocalDate、java.time.LocalDateTime、java.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はサーバーのタイムゾーンの影響を受けません。DateTime,DateTime64はサーバーまたはセッションのタイムゾーンに依存します。DateTimeおよびDateTime64は、getObject(colIndex, ZonedDateTime.class)を使用するとZonedDateTimeとして取得できます。
ネスト型
| ClickHouse 型 | JDBC 型 | Java クラス |
|---|---|---|
| Array | ARRAY | java.sql.Array |
| Tuple | OTHER | com.clickhouse.data.Tuple |
| Map | JAVA_OBJECT | java.util.Map |
| Nested | ARRAY | java.sql.Array |
Arrayは、JDBC との互換性を保つため、デフォルトではjava.sql.Arrayにマッピングされます。これは、返される配列値についてより多くの情報を提供できるようにする目的もあり、型推論に有用です。ArrayはgetResultSet()メソッドを実装しており、元の配列と同じ内容を持つjava.sql.ResultSetを返します。- コレクション型を
java.lang.Stringとして読み取るべきではありません。配列内の文字列値に引用符が付かないなど、データの表現方法として妥当ではないためです。 Mapは、値をgetObject(columnIndex, Class<T>)メソッドでのみ読み取れるため、JAVA_OBJECTにマッピングされます。Mapは名前付きカラムを持たないため、java.sql.Struct型ではありません。
Tupleは異なる型を含み得るためObject[]にマッピングされており、Listとして扱うことは適切ではありません。TupleはgetObject(columnIndex, Array.class)メソッドを使用することでArrayとして取得できます。この場合、Array#baseTypeNameはTupleカラム定義を返します。
配列の書き込み
java.sql.Connection#createArrayOf を使用して java.sql.Array オブジェクトをインスタンス化してください。このオブジェクトは、異なるデータベース間で配列の扱いを統一するために設計されています。
Array のファクトリメソッドに設定を渡すには、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#getResultSet() メソッドを使用すると、配列要素を java.sql.ResultSet としてより統一的に読み取ることができます。配列要素の正確な型が不明な場合に便利です。
例
Tuple の書き込み
タプルは com.clickhouse.data.Tuple オブジェクトにマッピングされ、setObject(columnIndex, tuple) メソッドを呼び出してこのオブジェクトとして書き込む必要があります。
移植性を高めるために、タプルの書き込みには java.sql.Struct オブジェクトを使用することもできます。
例
Tuple の読み取り
メソッド getObject(columnIndex) は Object[] を返します。getObject(columnIndex, Array.class) メソッドを使用すると、タプルを java.sql.Array として読み取ることができます。
例
Mapの書き込み
Map はキーと値のペアを必要とするため (java.sql.Struct はキーと値のペアをサポートしません) 、java.collections.Map オブジェクトとしてのみ書き込めます。
例
地図の読み方
Map 型は、getObject(columnIndex, Map.class) メソッドを使用することで java.collections.Map オブジェクトとして読み取れます。
例
Nested 型への書き込み
java.sql.Connection#createStruct を使用して java.sql.Struct オブジェクトをインスタンス化します。このオブジェクトは、複数のデータベース間でネスト構造の扱いを統一するために設計されています。
Struct のファクトリメソッドに設定を渡すには、Connection オブジェクトが必要です。
このメソッドは2つの引数を受け取ります:
typeName- ネストされた要素の型名。例えばNested(Tuple(Int32, String))->"Nested(Tuple(Int32, String))"。elements- ネストされた要素そのものです。たとえば[1, 'test']->new Object[] {1, 'test'}となります。
例
Nested 型の読み取り
Nested オブジェクトを読み取るには、ResultSet#getStruct(columnIndex, StructDescriptor) を使用します。このオブジェクトを使うと、任意の深さにネストされた要素へアクセスできます。
Struct#getResultSet() メソッドを使用すると、ネストされた要素を java.sql.ResultSet と同様の、より一貫した方法で読み取ることができます。これは、ネストされた要素の正確な型が不明な場合に有用です。
例
地理型
| ClickHouse 型 | JDBC 型 | Java クラス |
|---|---|---|
| Point | OTHER | double[] |
| Ring | OTHER | double[][] |
| Polygon | OTHER | double[][][] |
| MultiPolygon | OTHER | double[][][][] |
Nullable型とLowCardinality型
NullableとLowCardinalityは他の型をラップする特殊な型です。Nullableは、ResultSetMetaDataが返す型名の形式に影響します。
特殊型
| ClickHouse 型 | JDBC 型 | Java クラス |
|---|---|---|
| UUID | OTHER | java.util.UUID |
| IPv4 | OTHER | java.net.Inet4Address |
| IPv6 | OTHER | java.net.Inet6Address |
| JSON | OTHER | java.lang.String |
| AggregateFunction | OTHER | (バイナリ表現) |
| SimpleAggregateFunction | (ラップされた型) | (ラップされたクラス) |
UUIDは JDBC 標準の型ではありませんが、JDK に含まれています。デフォルトでは、getObject()メソッドからjava.util.UUIDが返されます。getObject(columnIndex, String.class)メソッドを使用すると、UUIDをStringとして読み書きできます。IPv4とIPv6は JDBC の標準型ではありませんが、JDK の一部です。デフォルトでは、getObject()メソッドで取得するとjava.net.Inet4Addressとjava.net.Inet6Addressが返されます。IPv4およびIPv6は、getObject(columnIndex, String.class)メソッドを使用することでStringとして読み書きできます。
日付、時刻、タイムゾーンの処理
ドライバーが日付/時刻およびタイムスタンプを処理する際の一般的な落とし穴や動作ロジックについては、日付/時刻ガイドを参照してください。
接続の作成
認証情報と設定の指定
単純なステートメント
Insert
HikariCP
詳細情報
詳細については、GitHubリポジトリおよびJavaクライアントのドキュメントを参照してください。
トラブルシューティング
ログ
このドライバはログに slf4j を使用し、classpath 上で最初に利用可能な実装を使用します。
大量挿入時のJDBCタイムアウトの解決
ClickHouseで実行時間が長くなる大規模な挿入 (INSERT) を行う際、次のようなJDBCタイムアウトエラーが発生することがあります:
これらのエラーはデータ挿入プロセスを妨げ、システムの安定性に影響を与える可能性があります。この問題に対処するには、クライアントのOS上のいくつかのタイムアウト設定を調整する必要がある場合があります。
Mac OS
macOS では、以下の設定値を調整することでこの問題を解消できます。
net.inet.tcp.keepidle: 60000net.inet.tcp.keepintvl: 45000net.inet.tcp.keepinit: 45000net.inet.tcp.keepcnt: 8net.inet.tcp.always_keepalive: 1
Linux
Linuxでは、同等の設定を行っただけでは問題が解決しない場合があります。Linuxにおけるソケットのキープアライブ設定の扱いが異なるため、追加の手順が必要です。以下の手順に従ってください:
/etc/sysctl.confまたは関連する設定ファイルで、以下の Linux カーネルパラメータを調整します:
net.inet.tcp.keepidle: 60000net.inet.tcp.keepintvl: 45000net.inet.tcp.keepinit: 45000net.inet.tcp.keepcnt: 8net.inet.tcp.always_keepalive: 1net.ipv4.tcp_keepalive_intvl: 75net.ipv4.tcp_keepalive_probes: 9net.ipv4.tcp_keepalive_time: 60 (デフォルトの 300 秒から短くすることも検討できます)
- カーネルパラメータを変更したら、次のコマンドを実行して変更内容を反映させます:
これらの設定を行った後は、クライアント側でソケットの Keep Alive オプションが有効になっていることを確認する必要があります:
移行ガイド
主な変更点
| 機能 | V1 (旧) | V2 (新) |
|---|---|---|
| トランザクション対応 | 一部サポート | サポートなし |
| レスポンスカラム名の変更 | 一部サポート | サポートなし |
| マルチステートメントSQL | サポートなし | 許可されていない |
| 名前付きパラメーター | サポートあり | サポートなし (JDBC仕様に含まれない) |
PreparedStatement を使ったストリーミングデータ | サポートあり | サポートなし |
- JDBC V2 はより軽量な実装として設計されており、その過程で一部の機能が削除されています。
- ストリーミングデータは JDBC 仕様や Java 自体の機能には含まれていないため、JDBC V2 ではサポートされません。
- JDBC V2 では明示的な設定が必要です。フェイルオーバー用のデフォルト設定は用意されていません。
- プロトコルは URL 内で明示的に指定する必要があります。ポート番号に基づいてプロトコルを暗黙的に判別することはありません。
設定変更
列挙型は次の2種類のみです:
com.clickhouse.jdbc.DriverProperties- ドライバー独自の設定プロパティです。com.clickhouse.client.api.ClientConfigProperties- クライアント構成プロパティです。クライアント構成の変更点については、Java クライアントのドキュメントを参照してください。
接続プロパティは次のように解析されます:
- まず URL からプロパティを解析し、そこで指定された値が他のすべてのプロパティより優先されます。
- ドライバーのプロパティはクライアント側には渡されません。
- エンドポイント (ホスト、ポート、プロトコル) は URL から解析して取得されます。
例:
データ型の変更点
数値型
| ClickHouse 型 | V1 との互換性 | JDBC 型 (V2) | Java クラス (V2) | JDBC 型 (V1) | Java クラス (V1) |
|---|---|---|---|---|---|
| Int8 | ✅ | TINYINT | java.lang.Byte | TINYINT | java.lang.Byte |
| Int16 | ✅ | SMALLINT | java.lang.Short | SMALLINT | java.lang.Short |
| Int32 | ✅ | INTEGER | java.lang.Integer | INTEGER | java.lang.Integer |
| Int64 | ✅ | BIGINT | java.lang.Long | BIGINT | java.lang.Long |
| Int128 | ✅ | OTHER | java.math.BigInteger | OTHER | java.math.BigInteger |
| Int256 | ✅ | OTHER | java.math.BigInteger | OTHER | java.math.BigInteger |
| UInt8 | ❌ | OTHER | java.lang.Short | OTHER | com.clickhouse.data.value.UnsignedByte |
| UInt16 | ❌ | OTHER | java.lang.Integer | OTHER | com.clickhouse.data.value.UnsignedShort |
| UInt32 | ❌ | OTHER | java.lang.Long | OTHER | com.clickhouse.data.value.UnsignedInteger |
| UInt64 | ❌ | OTHER | java.math.BigInteger | OTHER | com.clickhouse.data.value.UnsignedLong |
| UInt128 | ✅ | OTHER | java.math.BigInteger | OTHER | java.math.BigInteger |
| UInt256 | ✅ | OTHER | java.math.BigInteger | OTHER | java.math.BigInteger |
| Float32 | ✅ | REAL | java.lang.Float | REAL | java.lang.Float |
| Float64 | ✅ | DOUBLE | java.lang.Double | DOUBLE | java.lang.Double |
| Decimal32 | ✅ | DECIMAL | java.math.BigDecimal | DECIMAL | java.math.BigDecimal |
| Decimal64 | ✅ | DECIMAL | java.math.BigDecimal | DECIMAL | java.math.BigDecimal |
| Decimal128 | ✅ | DECIMAL | java.math.BigDecimal | DECIMAL | java.math.BigDecimal |
| Decimal256 | ✅ | DECIMAL | java.math.BigDecimal | DECIMAL | java.math.BigDecimal |
| Bool | ✅ | BOOLEAN | java.lang.Boolean | BOOLEAN | java.lang.Boolean |
- 最大の違いは、移植性を高めるために符号なし型が Java の型にマッピングされるようになった点です。
文字列型
| ClickHouse 型 | V1 との互換性 | JDBC 型 (V2) | Java クラス (V2) | JDBC 型 (V1) | Java クラス (V1) |
|---|---|---|---|---|---|
| String | ✅ | VARCHAR | java.lang.String | VARCHAR | java.lang.String |
| FixedString | ✅ | VARCHAR | java.lang.String | VARCHAR | java.lang.String |
FixedStringは両方のバージョンで、そのままの値として読み出されます。たとえば、'John'を格納したFixedString(10)は'John\0\0\0\0\0\0\0\0\0'として読み出されます。PreparedStatement#setBytesが使用されると、値はunhex('<hex_string>')に変換され、その結果がStringとして読み取られます。- 文字列は UTF-8 でエンコードされて保存されます。
日付/時刻型
| ClickHouse 型 | V1 との互換性 | JDBC 型 (V2) | Java クラス (V2) | JDBC 型 (V1) | Java クラス (V1) |
|---|---|---|---|---|---|
| Date | ❌ | DATE | java.sql.Date | DATE | java.time.LocalDate |
| Date32 | ❌ | DATE | java.sql.Date | DATE | java.time.LocalDate |
| DateTime | ❌ | TIMESTAMP | java.sql.Timestamp | TIMESTAMP | java.time.OffsetDateTime |
| DateTime64 | ❌ | TIMESTAMP | java.sql.Timestamp | TIMESTAMP | java.time.OffsetDateTime |
| Time | ✅ | TIME | java.sql.Time | 新しい型/未サポート | 新しい型/未サポート |
| Time64 | ✅ | TIME | java.sql.Time | 新しい型/サポート対象外 | 新しい型/サポート対象外 |
TimeとTime64は、V2 でのみサポートされる新しい型です。DateTimeとDateTime64は、JDBC との互換性を高めるためにjava.sql.Timestampにマッピングされます。
Enum型
| ClickHouse 型 | V1 との互換性 | JDBC 型 (V2) | Java クラス (V2) | JDBC 型 (V1) | Java クラス (V1) |
|---|---|---|---|---|---|
| Enum | ✅ | VARCHAR | java.lang.String | OTHER | java.lang.String |
| Enum8 | ✅ | VARCHAR | java.lang.String | OTHER | java.lang.String |
| Enum16 | ✅ | VARCHAR | java.lang.String | OTHER | java.lang.String |
ネスト型
| ClickHouse 型 | V1 との互換性 | JDBC 型 (V2) | Java クラス (V2) | JDBC 型 (V1) | Java クラス (V1) |
|---|---|---|---|---|---|
| Array | ❌ | ARRAY | java.sql.Array | ARRAY | Object[] またはプリミティブ型配列 |
| Tuple | ❌ | OTHER | Object[] | STRUCT | java.sql.Struct |
| Map | ❌ | JAVA_OBJECT | java.util.Map | STRUCT | java.util.Map |
| Nested | ❌ | ARRAY | java.sql.Array | STRUCT | java.sql.Struct |
- In V2 では、
Arrayは JDBC との互換性を維持するため、デフォルトでjava.sql.Arrayにマッピングされます。これは返される配列値に関する情報量を増やし、型推論に役立てるためでもあります。 - In V2 では、
ArrayはgetResultSet()メソッドを実装し、元の配列と同一の内容を持つjava.sql.ResultSetを返します。 - V1 では
Mapに対してSTRUCTを使用していますが、常にjava.util.Mapオブジェクトを返します。V2 では、MapをJAVA_OBJECTにマッピングすることでこの問題を解消しています。 - V1 は
Tupleに対してSTRUCTを使用しますが、常にList<Object>オブジェクトを返します。V2 ではTupleをOTHERにマッピングし、デフォルトでObject[]を返します。 - V2ではタプルの書き込みに使用する
com.clickhouse.data.Tuple#Tupleが導入されました。これにより、値がタプルか配列かを簡単に判別できるようになりました。 PreparedStatement#setBytesとResultSet#getBytesはコレクション型に対しては使用できません。これらのメソッドはバイト列を扱うためのものです。- 通常、Array 型の読み書きには
java.sql.Arrayを使用します。JDBC ドライバーはこれに完全対応しています。 - V2 では
NestedはArrayにマッピングされ、タプルの配列として扱われます。 - V2 では
java.sql.Structに対するサポートは部分的なものにとどまります。これは、Structが Array 型と非常によく似た型であり、キーと値のペアをサポートしないためです。StructはTuple値の書き込みに使用できます。
地理型
| ClickHouse 型 | V1 との互換性 | JDBC 型 (V2) | Java クラス (V2) | JDBC 型 (V1) | Java クラス (V1) |
|---|---|---|---|---|---|
| Point | ✅ | OTHER | double[] | OTHER | double[] |
| Ring | ✅ | OTHER | double[][] | OTHER | double[][] |
| Polygon | ✅ | OTHER | double[][][] | OTHER | double[][][] |
| MultiPolygon | ✅ | OTHER | double[][][][] | OTHER | double[][][][] |
Nullable型とLowCardinality型
NullableとLowCardinalityは他の型をラップする特殊な型です。- V2 ではこれらの型に変更はありません。
特殊型
| ClickHouse 型 | V1 互換 | JDBC 型 (V2) | Java クラス (V2) | JDBC 型 (V1) | Java クラス (V1) |
|---|---|---|---|---|---|
| JSON | ❌ | OTHER | java.lang.String | サポートされていません | サポートされていません |
| AggregateFunction | ✅ | OTHER | (バイナリ表現) | OTHER | (バイナリ表現) |
| SimpleAggregateFunction | ✅ | (ラップされた型) | (ラップされたクラス) | (ラップされた型) | (ラップされたクラス) |
| UUID | ✅ | OTHER | java.util.UUID | VARCHAR | java.util.UUID |
| IPv4 | ✅ | OTHER | java.net.Inet4Address | VARCHAR | java.net.Inet4Address |
| IPv6 | ✅ | OTHER | java.net.Inet6Address | VARCHAR | java.net.Inet6Address |
| Dynamic | ❌ | OTHER | java.lang.Object | サポートなし | サポートなし |
| Variant | ❌ | OTHER | java.lang.Object | サポートなし | サポートなし |
- V1 では
UUIDに対してVARCHARを使用しますが、常にjava.util.UUIDオブジェクトを返します。V2 では、UUIDをOTHERにマッピングすることでこの問題を解消し、java.util.UUIDオブジェクトを返します。 - V1 では
IPv4とIPv6に対してVARCHARを使用しますが、常にjava.net.Inet4Addressおよびjava.net.Inet6Addressオブジェクトを返します。V2 では、IPv4とIPv6をOTHERにマッピングすることでこの問題を解消し、java.net.Inet4Addressおよびjava.net.Inet6Addressオブジェクトを返します。 DynamicとVariantは V2 で導入された新しい型です。V1 ではサポートされていません。JSONはDynamic型を基盤としているため、V2 でのみサポートされています。- IPv4およびIPv6の値は、
getBytes(columnIndex)メソッドを使用してbyte[]として読み取ることもできます。ただし、これらの型については専用クラスを使用することが推奨されます。 - V2 では、IP アドレスを数値として読み取ることはサポートしていません。IP アドレスの数値への変換は、
InetAddressクラス群で行う方がより適切な実装と考えられているためです。
データベースメタデータの変更
- V2 ではデータベースを指す名称として
Schemaのみを使用します。Catalogという名称は将来のために予約されています。 - V2 は
DatabaseMetaData.supportsTransactions()およびDatabaseMetaData.supportsSavepoints()に対してfalseを返します。これは今後の開発で変更される予定です。