Java Client

**Signatures**

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

**Parameters**

`clazz` - Class representing the POJO used to read/write data.

`schema` - Data schema to use for matching with POJO properties.

**Examples**

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

## Usage Examples[​](#usage-examples "Direct link to Usage Examples")

Complete examples code is stored in the repo in a 'example` [folder](https://github.com/ClickHouse/clickhouse-java/tree/main/examples):

- [client-v2](https://github.com/ClickHouse/clickhouse-java/tree/main/examples/client-v2) - main set of examples.
- [demo-service](https://github.com/ClickHouse/clickhouse-java/tree/main/examples/demo-service) - example of how to use the client in a Spring Boot application.
- [demo-kotlin-service](https://github.com/ClickHouse/clickhouse-java/tree/main/examples/demo-kotlin-service) - example of how to use the client in Ktor (Kotlin) application.

## Reading Data[​](#reading-data "Direct link to Reading Data")

There are two common ways to read data:

- `query()` method that returns low-level `QueryResponse` object that contains `InputStream` with data. Usually combined with `ClickHouseBinaryFormatReader` for streaming reads but
  can be used with any other custom reader implementation. `QueryResponse` also provides access to the result set metadata and metrics.
- `queryAll()` method and using `GenericRecord` for convenient row access. In this case the whole result set is loaded into memory.
- `queryRecords()` method that returns `com.clickhouse.client.api.query.Records` - an iterator for `GenericRecord` objects. This method uses streaming approach
  (no data is loaded into memory) and utilises `GenericRecord` to access data.

**Note:** streaming approach requires fast read otherwise it may cause server write timeout because data is read directly from the network stream.

### Reading Arrays[​](#reading-arrays "Direct link to Reading Arrays")

**`ClickHouseBinaryFormatReader` Methods**

- `getList(...)` - reads any `Array(...)` as `List<T>`. Good default for flexible typed reads. Supports nested arrays.
- `getByteArray(...)`, `getShortArray(...)`, `getIntArray(...)`, `getLongArray(...)`, `getFloatArray(...)`, `getDoubleArray(...)`, `getBooleanArray(...)` - best for 1D arrays of primitive-compatible values.
- `getStringArray(...)` - for `Array(String)` (and enum values represented as names).
- `getObjectArray(...)` - generic option for any `Array(...)` element type, including nested arrays. Use to read arrays with nullable values and nested arrays.

Index-based and name-based overloads are available for all methods. Index is 1-based. Index-based do dirrect access to a column.
Name-based methods require index lookup each time.

```
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` Methods**

- `getList(...)` - reads any `Array(...)` as `List<T>`. Good default for flexible typed reads. Supports nested arrays.
- `getByteArray(...)`, `getShortArray(...)`, `getIntArray(...)`, `getLongArray(...)`, `getFloatArray(...)`, `getDoubleArray(...)`, `getBooleanArray(...)` - best for 1D arrays of primitive-compatible values.
- `getStringArray(...)` - for `Array(String)` (and enum values represented as names).
- `getObjectArray(...)` - generic option for any `Array(...)` element type, including nested arrays. Use to read arrays with nullable values and nested arrays.

Index-based and name-based overloads are available for all methods. Index is 1-based. Index-based do dirrect access to a column.
Name-based methods require index lookup each time.

```
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
    }
}


## Migration Guide \{#migration_guide}


Old client (V1) was using `com.clickhouse.client.ClickHouseClient#builder` as start point. The new client (V2) uses similar pattern with `com.clickhouse.client.api.Client.Builder`. Main
differences are:
- no service loader is used to grab implementation. The `com.clickhouse.client.api.Client` is facade class for all kinds of implementation in the future.
- a fewer sources of configuration: one is provided to the builder and one is with operation settings (`QuerySettings`, `InsertSettings`). Previous version had configuration per node and was loading
env. variables in some cases.

### Configuration Parameters Match \{#migration_from_v1_config}

There are 3 enum classes related to configuration in V1:
- `com.clickhouse.client.config.ClickHouseDefaults` - configuration parameters that supposed to be set in most use cases. Like `USER` and `PASSWORD`.
- `com.clickhouse.client.config.ClickHouseClientOption` - configuration parameters specific for the client. Like `HEALTH_CHECK_INTERVAL`.
- `com.clickhouse.client.http.config.ClickHouseHttpOption` - configuration parameters specific for HTTP interface. Like `RECEIVE_QUERY_PROGRESS`.

They were designed to group parameters and provide clear separation. However in some cases it lead to a confusion (is there a difference between `com.clickhouse.client.config.ClickHouseDefaults#ASYNC` and
`com.clickhouse.client.config.ClickHouseClientOption#ASYNC`). The new V2 client uses `com.clickhouse.client.api.Client.Builder` as single dictionary of all possible client configuration options.There is
`com.clickhouse.client.api.ClientConfigProperties` where all configuration parameter names are listed.

Table below shows what old options are supported in the new client and their new meaning.

**Legend:** ✔ = supported, ✗ = dropped

<Tabs groupId="v1-migration">
<TabItem value="connection-auth" label="Connection & Auth">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseDefaults#HOST` | `Client.Builder#addEndpoint` | |
| `ClickHouseDefaults#PROTOCOL` | ✗ | Only HTTP supported in V2 |
| `ClickHouseDefaults#DATABASE`<br/>`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`<br/>`ClickHouseHttpOption#KEEP_ALIVE_TIMEOUT` | `Client.Builder#setKeepAliveTimeout` | |
| `ClickHouseHttpOption#CONNECTION_REUSE_STRATEGY` | `Client.Builder#setConnectionReuseStrategy` | |
| `ClickHouseHttpOption#USE_BASIC_AUTHENTICATION` | `Client.Builder#useHTTPBasicAuth` | |

</TabItem>

<TabItem value="ssl" label="SSL & Security">