JDBC-драйвер
clickhouse-jdbc реализует стандартный интерфейс JDBC с использованием последней версии Java-клиента.
Рекомендуется напрямую использовать последнюю версию Java-клиента, если критичны производительность или прямой доступ.
Требования к среде
- OpenJDK версии >= 8
Настройка
- Maven
- Gradle (Kotlin)
- Gradle
Если вы используете JDBC-драйвер в приложении, которое требует добавления JAR-файла в classpath, вам необходимо загрузить JAR-файл по следующему адресу:
- Maven Central и добавьте его в classpath
- начиная с версии
0.9.4доступен артефакт https://mvnrepository.com/artifact/com.clickhouse/clickhouse-jdbc-all - используйте квалификатор
all, чтобы получить JAR‑файл, включающий всеshaded‑зависимости.
- начиная с версии
- или из официального репозитория здесь
Настройка
Класс драйвера: 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¶m2=value2][#tag1,tag2,...], например:
jdbc:clickhouse:http://localhost:8123jdbc:clickhouse:https://localhost:8443?ssl=true
Обратите внимание на следующие особенности синтаксиса URL:
- только одна конечная точка может быть указана в URL
- протокол следует указывать, если он отличается от протокола по умолчанию — 'HTTP'
- порт следует указывать, если используется порт, отличный от порта по умолчанию '8123'
- драйвер не определяет протокол по порту, его нужно указывать явно
- Параметр
sslне требуется, если протокол указан явно.
Свойства соединения
Основные параметры конфигурации определены в Java-клиенте. Их следует передавать драйверу без изменений. У драйвера есть собственные свойства, которые не входят в конфигурацию клиента; они перечислены ниже.
Свойства драйвера:
| Свойство | По умолчанию | Описание |
|---|---|---|
disable_frameworks_detection | true | Отключить определение фреймворков для User-Agent |
jdbc_ignore_unsupported_values | false | Подавляет SQLFeatureNotSupportedException в случаях, когда это не влияет на работу драйвера |
clickhouse.jdbc.v1 | false | Использовать устаревшую реализацию JDBC вместо новой |
default_query_settings | null | Позволяет передавать настройки запроса по умолчанию вместе с операциями запроса. |
jdbc_resultset_auto_close | true | Автоматически закрывает ResultSet при закрытии Statement |
beta.row_binary_for_simple_insert | false | Использовать реализацию PreparedStatement, основанную на записи в формате RowBinary. Работает только для запросов INSERT INTO ... VALUES. |
jdbc_resultset_auto_close | true | Автоматически закрывает ResultSet при закрытии Statement |
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 | Запоминать последние установленные роли для соединения. |
Все настройки сервера должны иметь префикс clickhouse_setting_ (как и в конфигурации клиента).
Пример конфигурации:
что будет эквивалентно следующему JDBC URL:
Примечание: нет необходимости кодировать в формате URL ни сам JDBC URL, ни свойства — это будет сделано автоматически.
Идентификация клиента
Существует два способа идентифицировать приложение, инициировавшее запрос: задать com.clickhouse.client.api.ClientConfigProperties#CLIENT_NAME через
свойства соединения или использовать метод java.sql.Connection#setClientInfo(String name, String value).
Оба способа приведут к следующему значению http_user_agent в журнале запросов:
Примечание: Рекомендуется использовать формат app_name/version для свойства client_name, поскольку это помогает идентифицировать приложение в журнале запросов.
Идентификация операции
JDBC-драйвер генерирует query_id для каждой операции (в настоящее время он добавляется в исключения, генерируемые сервером).
Чтобы задать log_comment для операции, используйте метод com.clickhouse.jdbc.StatementImpl#getLocalSettings. Для этого необходимо предварительно привести Statement или PreparedStatement к типу com.clickhouse.jdbc.StatementImpl.
Примечание: этот подход работает только при однопоточном использовании Statement, поскольку 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 | NUMERIC | java.math.BigInteger |
| Int256 | NUMERIC | java.math.BigInteger |
| UInt8 | SMALLINT | java.lang.Short |
| UInt16 | INTEGER | java.lang.Integer |
| UInt32 | BIGINT | java.lang.Long |
| UInt64 | NUMERIC | java.math.BigInteger |
| UInt128 | NUMERIC | java.math.BigInteger |
| UInt256 | NUMERIC | java.math.BigInteger |
| Float32 | FLOAT | 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, и наоборот.:rs.getObject(1, Float64.class)вернёт значение типаFloat64из столбцаInt8.rs.getLong(1)вернёт значение типаLongиз столбцаInt8.rs.getByte(1)может вернуть значение типаByteиз столбцаInt16, если оно попадает в диапазонByte.
- Преобразование из более широкого типа данных в более узкий не рекомендуется из‑за риска повреждения данных.
- Тип
Boolтоже ведёт себя как числовой. - Все числовые типы можно считывать как
java.lang.String. - Существует проблема с сохранением значения
Float.MAX_VALUEиз Java как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считывается как есть и дополняется нулевыми байтами до длины столбца. (Например,FixedString(10)для'John'будет прочитан как'John\0\0\0\0\0\0\0\0\0'.)
Типы Enum
| Тип ClickHouse | Тип JDBC | Класс Java |
|---|---|---|
| Enum8 | VARCHAR | java.lang.String |
| Enum16 | VARCHAR | java.lang.String |
Enum8иEnum16по умолчанию сопоставляются с типомjava.lang.String.- Значения Enum можно считывать как числовые значения, используя соответствующий метод‑геттер или метод
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 сопоставляются с типами
java.sqlдля лучшей совместимости с JDBC. Однако получить значения типовjava.time.LocalDate,java.time.LocalDateTime,java.time.LocalTimeможно, используяResultSet#getObject(columnIndex, Class<T>)и передав соответствующий класс в качестве второго аргумента.rs.getObject(1, java.time.LocalDate.class)вернёт значение типаjava.time.LocalDateиз столбцаDate.rs.getObject(1, java.time.LocalDateTime.class)вернёт значение типаjava.time.LocalDateTimeиз столбцаDateTime.rs.getObject(1, java.time.LocalTime.class)вернёт значение типаjava.time.LocalTimeиз столбцаTime.
Date,Date32,Time,Time64не зависят от часового пояса сервера.DateTime,DateTime64зависят от часового пояса сервера или сессии.DateTimeиDateTime64можно получить в видеZonedDateTime, вызвавgetObject(colIndex, ZonedDateTime.class).
Вложенные типы
| Тип ClickHouse | Тип JDBC | Класс Java |
|---|---|---|
| Array | ARRAY | java.sql.Array |
| Tuple | OTHER | com.clickhouse.data.Tuple |
| Map | OTHER | java.util.Map |
| Nested | ARRAY | java.sql.Array |
Arrayпо умолчанию сопоставляется сjava.sql.Arrayдля совместимости с JDBC. Это также позволяет получить больше информации о возвращаемом значении массива, что полезно для вывода типов.Arrayреализует методgetResultSet(), который возвращаетjava.sql.ResultSetс тем же содержимым, что и исходный массив.- Типы коллекций не следует считывать как
java.lang.String, поскольку это некорректный способ представления данных (например, строковые значения в массиве не заключаются в кавычки). Mapсопоставляется сOTHER, поскольку значение можно получить только с помощью методаgetObject(columnIndex, Class<T>).Mapне являетсяjava.sql.Struct, поскольку в нём нет именованных столбцов.
Tupleсопоставляется сObject[], так как может содержать значения разных типов, а использованиеListнедопустимо.Tupleможно прочитать какArray, используя методgetObject(columnIndex, Array.class). В этом случаеArray#baseTypeNameвернёт определение столбцаTuple.
Метаданные типа элементов массива
Array.getBaseTypeName() возвращает имя типа элемента ClickHouse; Array.getBaseType() возвращает код типа JDBC.
JDBC V2 сохраняет полные сигнатуры типов (типы-обёртки, параметры типов), которые V1 отбрасывает.
Общие правила сопоставления для массивов:
| Тип ClickHouse | getBaseTypeName() | getBaseType() |
|---|---|---|
Array(<Примитивный тип>) | <Примитивный тип> | <Примитивный тип JDBC> |
Array(<Parameterized Type>(<N>)) | <Параметризованный тип>(<N>) | <JDBC-тип базового типа> |
Array(Nullable(<Type>)) | Nullable(<Type>) | <JDBC-тип внутреннего типа> |
Array(LowCardinality(<Type>)) | LowCardinality(<Type>) | <тип JDBC внутреннего Type> |
Array(Array(...(<Type>))) | <Type> (наиболее вложенный элемент) | <тип JDBC самого внутреннего типа> |
Array(Tuple(...)) | Tuple(...) (полное определение) | OTHER |
Array(Enum8(...)) / Array(Enum16(...)) | Enum8(...) / Enum16(...) (полное определение) | VARCHAR |
Notes on the rules above:
- Типы-обёртки (
Nullable,LowCardinality) сохраняются вgetBaseTypeName(), ноgetBaseType()возвращает JDBC-код вложенного типа. - В метаданных вложенные массивы разворачиваются:
getBaseTypeName()возвращает тип самого внутреннего элемента, не являющегося массивом, а не тип непосредственного дочернего элемента. - Параметризованные типы (
FixedString(N), полные определенияEnum/Tuple) сохраняют параметры вgetBaseTypeName().
Примеры:
| Тип ClickHouse (Пример) | getBaseTypeName() | getBaseType() |
|---|---|---|
| Array(Int8) | Int8 | TINYINT |
| Array(Int16) | Int16 | SMALLINT |
| Array(Int32) | Int32 | INTEGER |
| Array(Int64) | Int64 | BIGINT |
| Array(UInt8) | UInt8 | SMALLINT |
| Array(UInt16) | UInt16 | INTEGER |
| Array(UInt32) | UInt32 | BIGINT |
| Array(UInt64) | UInt64 | NUMERIC |
| Array(Float32) | Float32 | FLOAT |
| Array(Float64) | Float64 | DOUBLE |
| Array(String) | String | VARCHAR |
| Array(FixedString(8)) | FixedString(8) | VARCHAR |
| Array(Bool) | Bool | BOOLEAN |
| Array(Date) | Date | DATE |
| Array(DateTime) | DateTime | TIMESTAMP |
| Array(UUID) | UUID | OTHER |
| Array(Nullable(Int32)) | Nullable(Int32) | INTEGER |
| Array(Nullable(String)) | Nullable(String) | VARCHAR |
| Array(LowCardinality(String)) | LowCardinality(String) | VARCHAR |
| Array(LowCardinality(Nullable(String))) | LowCardinality(Nullable(String)) | VARCHAR |
| Array(Array(Int32)) | Int32 | INTEGER |
| Array(Array(Array(String))) | String | VARCHAR |
| Array(Tuple(name String, val Int32)) | Tuple(name String, val Int32) | OTHER |
| Array(Enum8('alpha' = 1, 'beta' = 2, 'gamma' = 3)) | Enum8('alpha' = 1, 'beta' = 2, 'gamma' = 3) | VARCHAR |
- В V2 метод
getBaseTypeName()сохраняет полную сигнатуру типа, включая типы-обёртки (Nullable,LowCardinality) и параметры типа (FixedString(8), полные определенияEnumиTuple). В V1 всё это отбрасывается, и возвращается только имя базового типа. - Массивы
TupleиспользуютOTHER (1111)в V2 вместоSTRUCT (2002), поскольку кортежи в ClickHouse имеют именованные поля, аjava.sql.Structих не поддерживает. - Для массивов
UUIDв V2 используетсяOTHER (1111), как и для скалярногоUUID. Enumсопоставляется сVARCHAR— элементы перечисления идентифицируются по строковому имени независимо от базовой числовой кодировки.
Запись массивов
Используйте java.sql.Connection#createArrayOf для создания объекта java.sql.Array. Этот объект предназначен для унификации работы с массивами в разных базах данных.
Соединение требуется, чтобы передать конфигурацию фабричному методу Array.
Метод принимает два аргумента:
typeName- имя типа элементов массива. Например,Array(Int32)->"Int32".elements- сами элементы массива. Например,[[1, 2, 3], [4, 5, 6]]->new Integer[][] {{1, 2, 3}, {4, 5, 6}}.
Кортеж можно представить как Object[] или как java.sql.Struct (см. ниже, как записывать кортежи).
Пример
Чтение массивов
Используйте ResultSet#getArray(columnIndex) для чтения объекта Array. Этот объект можно использовать для доступа к массиву любой глубины вложенности.
Метод Array#getResultSet() можно использовать для чтения элементов массива в более унифицированном виде как java.sql.ResultSet. Это полезно,
когда точный тип элементов массива неизвестен.
Пример
Запись кортежей
Кортежи сопоставляются с объектом com.clickhouse.data.Tuple и должны записываться в виде этого объекта с помощью метода setObject(columnIndex, tuple).
Для лучшей переносимости можно использовать объект java.sql.Struct для записи кортежей.
Пример
Чтение кортежей
Метод getObject(columnIndex) возвращает Object[]. Кортежи можно прочитать как java.sql.Array, используя метод getObject(columnIndex, Array.class).
Пример
Запись в Map
Map можно записывать только как объект java.collections.Map, поскольку для этого типа требуются пары ключ-значение (java.sql.Struct не поддерживает пары ключ-значение).
Пример
Чтение типов Map
Map можно получить как объект java.collections.Map, используя метод getObject(columnIndex, Map.class).
Пример
Запись в Nested
Используйте java.sql.Connection#createStruct для создания экземпляра java.sql.Struct. Этот объект предназначен для унифицированной обработки вложенных структур в различных СУБД.
Объект Connection необходим для передачи конфигурации в фабричный метод Struct.
Метод принимает два аргумента:
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. Это полезно,
когда точный тип вложенных элементов заранее неизвестен.
Пример
Геотипы
| Тип 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.UUIDможно читать и записывать какStringс помощью методаgetObject(columnIndex, String.class).IPv4иIPv6не относятся к стандартным типам JDBC. Однако они входят в стандартную библиотеку JDK. По умолчанию методgetObject()возвращает объектыjava.net.Inet4Addressиjava.net.Inet6Address.IPv4иIPv6можно считывать и записывать как значения типаStringс помощью методаgetObject(columnIndex, String.class).
Обработка дат, времени и часовых поясов
Ознакомьтесь с руководством по Date/Time, в котором описаны типичные ошибки и логика работы драйвера при обработке значений Date/Time и временных меток.
Создание соединения
Предоставление учётных данных и настроек
Простая команда
Вставка данных
HikariCP
Дополнительная информация
Дополнительную информацию см. в нашем репозитории GitHub и документации Java-клиента.
Устранение неполадок
Логирование
Драйвер использует slf4j для логирования и берёт первую доступную реализацию из classpath.
Устранение таймаута JDBC при больших вставках данных
При выполнении больших вставок в ClickHouse с длительным временем выполнения могут возникать ошибки тайм-аута JDBC, такие как:
Эти ошибки могут нарушить процесс вставки данных и повлиять на стабильность системы. Для устранения этой проблемы может потребоваться изменить несколько настроек таймаута в операционной системе клиента.
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 управляет параметрами keep-alive сокетов, требуются дополнительные действия. Выполните следующие шаги:
- Настройте следующие параметры ядра Linux в файле
/etc/sysctl.confили другом соответствующем конфигурационном файле:
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 V2, так как потоковая передача не предусмотрена спецификацией JDBC и Java.
- JDBC V2 требует явной конфигурации. Не предоставляет настроек отказоустойчивости по умолчанию.
- Протокол в URL должен быть указан явно; определение протокола по номеру порта не выполняется.
Изменения в конфигурации
Существует только два перечисления:
com.clickhouse.jdbc.DriverProperties- собственные свойства конфигурации драйвера.com.clickhouse.client.api.ClientConfigProperties- свойства конфигурации клиента. Изменения в конфигурации клиента описаны в документации по Java‑клиенту.
Свойства подключения разбираются следующим образом:
- Сначала из URL разбираются свойства; они переопределяют все остальные.
- Свойства драйвера не передаются клиенту.
- Конечные точки (host, port, protocol) разбираются из URL.
Пример:
Изменения типов данных
Числовые типы
| Тип ClickHouse | Совместимо с V1 | Тип JDBC (V2) | Класс Java (V2) | Тип JDBC (V1) | Java Class (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 | ✅ | NUMERIC | java.math.BigInteger | NUMERIC | java.math.BigInteger |
| Int256 | ✅ | NUMERIC | java.math.BigInteger | NUMERIC | java.math.BigInteger |
| UInt8 | ❌ | SMALLINT | java.lang.Short | SMALLINT | com.clickhouse.data.value.UnsignedByte |
| UInt16 | ❌ | INTEGER | java.lang.Integer | INTEGER | com.clickhouse.data.value.UnsignedShort |
| UInt32 | ❌ | BIGINT | java.lang.Long | BIGINT | com.clickhouse.data.value.UnsignedInteger |
| UInt64 | ❌ | NUMERIC | java.math.BigInteger | NUMERIC | com.clickhouse.data.value.UnsignedLong |
| UInt128 | ✅ | NUMERIC | java.math.BigInteger | NUMERIC | java.math.BigInteger |
| UInt256 | ✅ | NUMERIC | java.math.BigInteger | NUMERIC | java.math.BigInteger |
| Float32 | ✅ | FLOAT | java.lang.Float | FLOAT | 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считывается «как есть» в обеих версиях. Например,FixedString(10)для'John'будет прочитан как'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_WITH_TIMEZONE | java.time.OffsetDateTime |
| DateTime64 | ❌ | TIMESTAMP | java.sql.Timestamp | TIMESTAMP_WITH_TIMEZONE | java.time.OffsetDateTime |
| Time | ✅ | TIME | java.sql.Time | новый тип / не поддерживается | новый тип / не поддерживается |
| Time64 | ✅ | TIME | java.sql.Time | новый тип / не поддерживается | новый тип / не поддерживается |
TimeиTime64поддерживаются в V2 только как новые типы.DateTimeиDateTime64сопоставляются сjava.sql.Timestampдля повышения совместимости с JDBC.
Типы 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[] или массив примитивных типов |
| Кортеж | ❌ | 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 |
- В V2
Arrayпо умолчанию сопоставляется сjava.sql.Arrayдля совместимости с JDBC. Это также позволяет получить больше информации о возвращаемом значении массива, что полезно для вывода типов. - В V2
Arrayреализует методgetResultSet(), который возвращаетjava.sql.ResultSetс тем же содержимым, что и исходный массив. - V1 использует
STRUCTдляMap, но всегда возвращает объект типаjava.util.Map. V2 исправляет это, сопоставляяMapсJAVA_OBJECT. - V1 использует
STRUCTдляTuple, но всегда возвращает объект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, поскольку он по своей структуре очень похож на тип 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 Class (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.Object | не поддерживается | не поддерживается |
| Variant | ❌ | OTHER | java.Object | не поддерживается | не поддерживается |
- V1 использует
VARCHARдляUUID, но всегда возвращает объектjava.util.UUID. V2 устраняет это, сопоставляяUUIDсOTHERи также возвращая объектjava.util.UUID. - V1 использует
VARCHARдляIPv4иIPv6, но всегда возвращает объекты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 можно считывать в виде массива байтов
byte[]с помощью методаgetBytes(columnIndex). Однако рекомендуется использовать специальные классы для этих типов. - V2 не поддерживает чтение IP-адресов как числовых значений, поскольку такое преобразование лучше выполнять в классах InetAddress.
Изменения метаданных базы данных
- V2 использует только термин
Schemaдля обозначения баз данных. ТерминCatalogзарезервирован для будущего использования. - V2 возвращает
falseдляDatabaseMetaData.supportsTransactions()иDatabaseMetaData.supportsSavepoints(). В будущих версиях это поведение будет изменено.