> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Java ClickHouse Connector

# Java 클라이언트

export const WideTableWrapper = ({children}) => {
  const containerStyle = {
    overflow: "auto",
    maxWidth: "100%"
  };
  return <div style={containerStyle}>{children}</div>;
};

<a id="migration_from_v1_config" />

<View title="v0.8+">
  DB 서버와 프로토콜을 통해 통신하기 위한 Java 클라이언트 라이브러리입니다. 현재 구현은 [HTTP 인터페이스](/ko/concepts/features/interfaces/http)만 지원합니다.
  이 라이브러리는 서버에 요청을 전송하기 위한 자체 API를 제공하며, 다양한 바이너리 데이터 포맷(RowBinary\* & Native\*)을 처리하기 위한 도구도 함께 제공합니다.

  ## Setup

  * Maven Central (프로젝트 웹 페이지): [https://mvnrepository.com/artifact/com.clickhouse/client-v2](https://mvnrepository.com/artifact/com.clickhouse/client-v2)
  * 나이틀리 빌드(리포지토리 링크): [https://central.sonatype.com/repository/maven-snapshots/](https://central.sonatype.com/repository/maven-snapshots/)
  * 이전 Nightly 빌드용 아티팩토리(리포지토리 링크): [https://s01.oss.sonatype.org/content/repositories/snapshots/](https://s01.oss.sonatype.org/content/repositories/snapshots/)

  <br />

  <Tabs>
    <Tab title="Maven">
      ```xml theme={null}
      <dependency>
          <groupId>com.clickhouse</groupId>
          <artifactId>client-v2</artifactId>
          <version>0.9.8</version>
      </dependency>
      ```
    </Tab>

    <Tab title="Gradle (Kotlin)">
      ```kotlin theme={null}
      // https://mvnrepository.com/artifact/com.clickhouse/client-v2
      implementation("com.clickhouse:client-v2:0.9.8")
      ```
    </Tab>

    <Tab title="Gradle">
      ```groovy theme={null}
      // https://mvnrepository.com/artifact/com.clickhouse/client-v2
      implementation 'com.clickhouse:client-v2:0.9.8'
      ```
    </Tab>
  </Tabs>

  <br />

  ## 초기화

  Client 객체는 `com.clickhouse.client.api.Client.Builder#build()`를 통해 초기화됩니다. 각 클라이언트는 고유한 Context를 가지며, 클라이언트 간에 객체는 공유되지 않습니다.
  Builder에는 편리한 설정을 위한 구성 메서드가 있습니다.

  예시:

  ```java showLineNumbers theme={null}
  Client client = new Client.Builder()
                  .addEndpoint("https://clickhouse-cloud-instance:8443/")
                  .setUsername(user)
                  .setPassword(password)
                  .build();
  ```

  `Client`는 `AutoCloseable`이므로 더 이상 필요하지 않을 때 닫아야 합니다.

  ### 인증(Authentication)

  인증은 초기화 단계에서 클라이언트별로 구성됩니다. 지원되는 인증 방법은 비밀번호, 액세스 토큰, SSL 클라이언트 인증서의 세 가지입니다.

  password를 통한 인증(authentication)은 `setUsername(String)` 및 `setPassword(String)`을 호출하여 username과 password를 설정해야 합니다:

  ```java showLineNumbers theme={null}
  Client client = new Client.Builder()
          .addEndpoint("https://clickhouse-cloud-instance:8443/")
          .setUsername(user)
          .setPassword(password)
          .build();
  ```

  액세스 토큰을 통한 인증(authentication)은 `setAccessToken(String)`을 호출하여 액세스 토큰을 설정해야 합니다:

  ```java showLineNumbers theme={null}
  Client client = new Client.Builder()
          .addEndpoint("https://clickhouse-cloud-instance:8443/")
          .setAccessToken(userAccessToken)
          .build();
  ```

  SSL 클라이언트 인증서로 인증하려면 `setUsername(String)`, `useSSLAuthentication(boolean)`, `setClientCertificate(String)`, `setClientKey(String)`를 각각 호출하여 사용자 이름을 설정하고 SSL 인증을 활성화한 뒤 클라이언트 인증서와 클라이언트 키를 설정해야 합니다:

  ```java showLineNumbers theme={null}
  Client client = new Client.Builder()
          .useSSLAuthentication(true)
          .setUsername("some_user")
          .setClientCertificate("some_user.crt")
          .setClientKey("some_user.key")
  ```

  <Note>
    SSL 인증은 SSL 라이브러리에서 발생하는 많은 오류가 충분한 정보를 제공하지 않기 때문에 운영 환경(production)에서는 트러블슈팅이 어려울 수 있습니다. 예를 들어 클라이언트 인증서와 키가 일치하지 않으면 서버가 즉시 connection을 종료합니다(HTTP의 경우, HTTP request가 전송되기 전인 connection 초기화 단계에서 종료되므로 응답도 전송되지 않습니다).

    인증서와 키를 검증하려면 [openssl](https://docs.openssl.org/master/man1/openssl/)과 같은 도구를 사용하십시오:

    * 키 무결성 확인: `openssl rsa -in [key-file.key] -check -noout`
    * 클라이언트 인증서에 사용자와 일치하는 CN이 있는지 확인:
      * 사용자 인증서에서 CN 가져오기 - `openssl x509 -noout -subject -in [user.cert]`
      * 동일한 값이 데이터베이스에 설정되어 있는지 확인: `select name, auth_type, auth_params from system.users where auth_type = 'ssl_certificate'` (`auth_params`에는 ` {"common_names":["some_user"]}`와 같은 값이 출력됩니다)
  </Note>

  ## 구성

  모든 설정은 인스턴스 메서드(구성 메서드라고도 함)로 정의되며, 각 값의 범위와 Context를 명확하게 나타냅니다.
  주요 구성 매개변수는 하나의 범위(클라이언트 또는 작업)에서 정의되고, 서로 재정의되지 않습니다.

  구성은 클라이언트 생성 시 정의됩니다. `com.clickhouse.client.api.Client.Builder`를 참조하십시오.

  ## 클라이언트 구성

  <Tabs>
    <Tab title="연결 및 엔드포인트">
      | 메서드                                                                     | 인수                                                                        | 설명                                                                  | 기본값       | 키                           |
      | ----------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------- | --------- | --------------------------- |
      | `addEndpoint(String endpoint)`                                          | `endpoint` - URL 형식의 서버 주소                                                | 사용 가능한 서버 목록에 서버 엔드포인트를 추가합니다. 현재는 엔드포인트 1개만 지원합니다.                 | `none`    | `none`                      |
      | `addEndpoint(Protocol protocol, String host, int port, boolean secure)` | `protocol` - 연결 프로토콜<br />`host` - IP 또는 호스트명<br />`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` - timeout 값<br />`unit` - 시간 단위                                 | 연결이 비활성 상태로 간주되기까지의 TTL을 설정합니다.                                     | `-1`      | `connection_ttl`            |
      | `setKeepAliveTimeout(long timeout, ChronoUnit unit)`                    | `timeout` - timeout 값<br />`unit` - 시간 단위                                 | HTTP 연결 keep-alive timeout을 설정합니다. Keep-Alive를 비활성화하려면 `0`으로 설정합니다. | -         | `http_keep_alive_timeout`   |
      | `setConnectionReuseStrategy(ConnectionReuseStrategy strategy)`          | `strategy` - `LIFO` 또는 `FIFO`                                             | 연결 풀이 사용할 전략을 선택합니다.                                                | `FIFO`    | `connection_reuse_strategy` |
      | `setDefaultDatabase(String database)`                                   | `database` - 데이터베이스 이름                                                    | 기본 데이터베이스를 설정합니다.                                                   | `default` | `database`                  |
    </Tab>

    <Tab title="인증">
      | 메서드                                                  | 인수                                      | 설명                                                                        | 기본값       | 키                     |
      | ---------------------------------------------------- | --------------------------------------- | ------------------------------------------------------------------------- | --------- | --------------------- |
      | `setUsername(String username)`                       | `username` - 인증에 사용할 사용자 이름             | 추가 구성에서 선택하는 인증 메서드에 사용할 사용자 이름을 설정합니다                                    | `default` | `user`                |
      | `setPassword(String password)`                       | `password` - 시크릿 값                      | 비밀번호 인증에 사용할 시크릿을 설정하며, 해당 인증 메서드가 사실상 선택됩니다                              | -         | `password`            |
      | `setAccessToken(String accessToken)`                 | `accessToken` - 액세스 토큰 문자열              | 해당 인증 메서드에 사용할 액세스 토큰을 설정합니다                                              | -         | `access_token`        |
      | `useSSLAuthentication(boolean useSSLAuthentication)` | `useSSLAuthentication` - SSL 인증 활성화 플래그 | SSL 클라이언트 인증서를 인증 메서드로 설정합니다.                                             | -         | `ssl_authentication`  |
      | `useHTTPBasicAuth(boolean useBasicAuth)`             | `useBasicAuth` - 활성화/비활성화 플래그           | 사용자 이름-비밀번호 인증에 기본 HTTP 인증을 사용할지 설정합니다. 특수 문자가 포함된 비밀번호에서 발생하는 문제를 해결합니다. | `true`    | `http_use_basic_auth` |
      | `useBearerTokenAuth(String bearerToken)`             | `bearerToken` - 인코딩된 Bearer 토큰          | Bearer 인증 사용 여부와 사용할 토큰을 지정합니다. 토큰은 그대로 전송됩니다.                            | -         | `bearer_token`        |
    </Tab>

    <Tab title="타임아웃 및 재시도">
      | 메서드                                                          | 인수                                          | 설명                                                | 기본값                                                          | 키                            |
      | ------------------------------------------------------------ | ------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------ | ---------------------------- |
      | `setConnectTimeout(long timeout, ChronoUnit unit)`           | `timeout` - 제한 시간 값<br />`unit` - 시간 단위     | 모든 아웃바운드 연결에 대한 연결 시작 timeout을 설정합니다.             | -                                                            | `connection_timeout`         |
      | `setConnectionRequestTimeout(long timeout, ChronoUnit unit)` | `timeout` - 제한 시간 값<br />`unit` - 시간 단위     | 연결 요청 timeout을 설정합니다. 이 설정은 풀에서 연결을 가져올 때만 적용됩니다. | `10000`                                                      | `connection_request_timeout` |
      | `setSocketTimeout(long timeout, ChronoUnit unit)`            | `timeout` - 제한 시간 값<br />`unit` - 시간 단위     | 읽기 및 쓰기 작업에 영향을 주는 소켓 timeout을 설정합니다.             | `0`                                                          | `socket_timeout`             |
      | `setExecutionTimeout(long timeout, ChronoUnit timeUnit)`     | `timeout` - 제한 시간 값<br />`timeUnit` - 시간 단위 | 쿼리의 최대 실행 timeout을 설정합니다.                         | `0`                                                          | `max_execution_time`         |
      | `retryOnFailures(ClientFaultCause ...causes)`                | `causes` - `ClientFaultCause`의 enum 상수      | 복구 가능하고 재시도할 수 있는 장애 유형을 설정합니다.                   | `NoHttpResponse` `ConnectTimeout` `ConnectionRequestTimeout` | `client_retry_on_failures`   |
      | `setMaxRetries(int maxRetries)`                              | `maxRetries` - 재시도 횟수                       | `retryOnFailures`에서 정의한 실패에 대한 최대 재시도 횟수를 설정합니다.  | `3`                                                          | `retry`                      |
    </Tab>

    <Tab title="소켓 옵션">
      | 메서드                                  | 인수                       | 설명                                                                             | 기본값    | 키                    |
      | ------------------------------------ | ------------------------ | ------------------------------------------------------------------------------ | ------ | -------------------- |
      | `setSocketRcvbuf(long size)`         | `size` - 바이트 단위 크기       | TCP 소켓 수신 버퍼를 설정합니다. 이 버퍼는 JVM 메모리 외부에 있습니다.                                   | `8196` | `socket_rcvbuf`      |
      | `setSocketSndbuf(long size)`         | `size` - 바이트 단위 크기       | TCP 소켓 송신 버퍼를 설정합니다. 이 버퍼는 JVM 메모리 외부에 있습니다.                                   | `8196` | `socket_sndbuf`      |
      | `setSocketKeepAlive(boolean value)`  | `value` - 활성화/비활성화 플래그   | 모든 TCP 소켓에 `SO_KEEPALIVE` 옵션을 설정합니다. TCP Keep Alive는 연결 상태를 확인하는 메커니즘을 활성화합니다. | -      | `socket_keepalive`   |
      | `setSocketTcpNodelay(boolean value)` | `value` - 활성화/비활성화 플래그   | 모든 TCP 소켓에 `SO_NODELAY` 옵션을 설정합니다. 이 TCP 옵션은 소켓이 가능한 한 빨리 데이터를 전송하도록 합니다.      | -      | `socket_tcp_nodelay` |
      | `setSocketLinger(int secondsToWait)` | `secondsToWait` - 초 단위 값 | 클라이언트가 생성하는 모든 TCP 소켓의 linger 시간을 설정합니다.                                       | -      | `socket_linger`      |
    </Tab>

    <Tab title="압축">
      | 메서드                                       | 인수                       | 설명                                               | 기본값     | 키                                          |
      | ----------------------------------------- | ------------------------ | ------------------------------------------------ | ------- | ------------------------------------------ |
      | `compressServerResponse(boolean enabled)` | `enabled` - 활성화/비활성화 플래그 | 서버가 응답을 압축할지 설정합니다.                              | `true`  | `compress`                                 |
      | `compressClientRequest(boolean enabled)`  | `enabled` - 활성화/비활성화 플래그 | 클라이언트가 요청을 압축할지 설정합니다.                           | `false` | `decompress`                               |
      | `useHttpCompression(boolean enabled)`     | `enabled` - 활성화/비활성화 플래그 | 해당 옵션이 활성화된 경우 클라이언트/서버 통신에 HTTP 압축을 사용할지 설정합니다. | -       | -                                          |
      | `appCompressedData(boolean enabled)`      | `enabled` - 활성화/비활성화 플래그 | 압축이 애플리케이션에서 처리된다는 것을 클라이언트에 알립니다.               | `false` | `app_compressed_data`                      |
      | `setLZ4UncompressedBufferSize(int size)`  | `size` - 바이트 단위 크기       | 데이터 스트림의 비압축 부분을 수신할 버퍼의 크기를 설정합니다.              | `65536` | `compression.lz4.uncompressed_buffer_size` |
      | `disableNativeCompression`                | `disable` - 비활성화 플래그     | 네이티브 압축을 비활성화합니다. `true`로 설정하면 네이티브 압축이 비활성화됩니다. | `false` | `disable_native_compression`               |
    </Tab>

    <Tab title="SSL/보안">
      | 메서드                                         | 인수                     | 설명                                                               | 기본값 | 키                    |
      | ------------------------------------------- | ---------------------- | ---------------------------------------------------------------- | --- | -------------------- |
      | `setSSLTrustStore(String path)`             | `path` - 로컬 시스템의 파일 경로 | 서버 호스트를 검증할 때 클라이언트가 SSL 트러스트스토어를 사용할지 설정합니다.                    | -   | `trust_store`        |
      | `setSSLTrustStorePassword(String password)` | `password` - 시크릿 값     | `setSSLTrustStore`로 지정한 SSL 트러스트스토어의 잠금을 해제하는 데 사용할 비밀번호를 설정합니다. | -   | `key_store_password` |
      | `setSSLTrustStoreType(String type)`         | `type` - 트러스트스토어 유형 이름 | `setSSLTrustStore`로 지정한 트러스트스토어의 유형을 설정합니다.                      | -   | `key_store_type`     |
      | `setRootCertificate(String path)`           | `path` - 로컬 시스템의 파일 경로 | 서버 호스트를 검증할 때 사용할 루트(CA) 인증서를 지정합니다.                             | -   | `sslrootcert`        |
      | `setClientCertificate(String path)`         | `path` - 로컬 시스템의 파일 경로 | SSL 연결을 시작할 때 사용하며 SSL 인증에 사용할 클라이언트 인증서 경로를 설정합니다.              | -   | `sslcert`            |
      | `setClientKey(String path)`                 | `path` - 로컬 시스템의 파일 경로 | 서버와의 SSL 통신을 암호화하는 데 사용할 클라이언트 개인 키를 설정합니다.                      | -   | `ssl_key`            |
      | `sslSocketSNI(String sni)`                  | `sni` - 서버 이름 문자열      | SSL/TLS 연결에서 SNI(Server Name Indication)에 사용할 서버 이름을 설정합니다.      | -   | `ssl_socket_sni`     |
    </Tab>

    <Tab title="프록시">
      | 메서드                                               | 인수                                                                | 설명                        | 기본값 | 키                                        |
      | ------------------------------------------------- | ----------------------------------------------------------------- | ------------------------- | --- | ---------------------------------------- |
      | `addProxy(ProxyType type, String host, int port)` | `type` - 프록시 유형<br />`host` - 프록시 호스트명 또는 IP<br />`port` - 프록시 포트 | 서버와 통신할 때 사용할 프록시를 설정합니다. | -   | `proxy_type`, `proxy_host`, `proxy_port` |
      | `setProxyCredentials(String user, String pass)`   | `user` - 프록시 사용자 이름<br />`pass` - 비밀번호                            | 프록시 인증에 사용할 자격 증명을 설정합니다. | -   | `proxy_user`, `proxy_password`           |
    </Tab>

    <Tab title="HTTP 및 헤더">
      | 메서드                                         | 인수                                         | 설명                                                                                                                                                                        | 기본값     | 키                                        |
      | ------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ---------------------------------------- |
      | `setHttpCookiesEnabled(boolean enabled)`    | `enabled` - 활성화/비활성화 플래그                   | HTTP 쿠키를 저장하고 서버에 다시 전송할지 설정합니다.                                                                                                                                          | -       | -                                        |
      | `httpHeader(String key, String value)`      | `key` - HTTP 헤더 키<br />`value` - 문자열 값     | 단일 HTTP 헤더의 값을 설정합니다. 이전 값은 덮어씁니다.                                                                                                                                        | `none`  | `none`                                   |
      | `httpHeader(String key, Collection values)` | `key` - HTTP 헤더 키<br />`values` - 문자열 값 목록 | 단일 HTTP 헤더의 여러 값을 설정합니다. 이전 값은 덮어씁니다.                                                                                                                                     | `none`  | `none`                                   |
      | `httpHeaders(Map headers)`                  | `headers` - HTTP headers를 담은 맵             | 여러 HTTP 헤더 값을 한 번에 설정합니다.                                                                                                                                                 | `none`  | `none`                                   |
      | `useHttpFormDataForQuery(boolean enable)`   | `enable` - 활성화/비활성화 플래그                    | 쿼리 매개변수를 URL 대신 요청 본문(request body)의 HTTP 폼 데이터로 전송할지 설정합니다. 서버 측 압축을 사용할 때만 동작합니다. 클라이언트 수준 압축이 활성화된 경우 각 매개변수가 multipart 콘텐츠로 전송되므로, 매개변수가 포함된 쿼리 요청에서는 해당 압축이 비활성화됩니다. | `false` | `client.http.use_form_request_for_query` |
    </Tab>

    <Tab title="서버 설정">
      | 메서드                                             | 인수                                  | 설명                                                                                                                                                             | 기본값       | 키                        |
      | ----------------------------------------------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ------------------------ |
      | `serverSetting(String name, String value)`      | `name` - 설정 이름<br />`value` - 설정 값  | 각 쿼리와 함께 서버에 전달할 설정을 지정합니다. 개별 작업 설정에서 이를 재정의할 수 있습니다. [설정 목록](/ko/concepts/features/configuration/settings/settings-query-level)                              | `none`    | `none`                   |
      | `serverSetting(String name, Collection values)` | `name` - 설정 이름<br />`values` - 설정 값 | 여러 값을 사용해 서버에 전달할 설정을 지정합니다. 예를 들면 [역할](/ko/concepts/features/interfaces/http#setting-role-with-query-parameters)이 있습니다                                        | `none`    | `none`                   |
      | `setOption("custom_settings_prefix", value)`    | `value` - 접두사 문자열                   | 서버에 전달되는 사용자 지정 설정의 접두사를 지정합니다. 서버 구성과 일치해야 합니다. [ClickHouse Docs](/ko/concepts/features/configuration/settings/settings-query-level#custom_settings)를 참조하십시오. | `custom_` | `custom_settings_prefix` |
    </Tab>

    <Tab title="시간대">
      | 메서드                                            | 인수                                 | 설명                                                                | 기본값    | 키                      |
      | ---------------------------------------------- | ---------------------------------- | ----------------------------------------------------------------- | ------ | ---------------------- |
      | `useServerTimeZone(boolean useServerTimeZone)` | `useServerTimeZone` - 활성화/비활성화 플래그 | DateTime 및 Date 컬럼 값을 디코딩할 때 클라이언트가 서버 시간대를 사용할지 설정합니다.           | `true` | `use_server_time_zone` |
      | `useTimeZone(String timeZone)`                 | `timeZone` - Java에서 유효한 시간대 ID     | DateTime 및 Date 컬럼 값을 디코딩할 때 지정된 시간대를 사용할지 설정합니다. 서버 시간대를 재정의합니다. | -      | `use_time_zone`        |
      | `setServerTimeZone(String timeZone)`           | `timeZone` - Java에서 유효한 시간대 ID     | 서버 측 시간대를 설정합니다. 기본값으로 UTC 시간대가 사용됩니다.                            | `UTC`  | `server_time_zone`     |
    </Tab>

    <Tab title="고급">
      | 메서드                                                                       | 인수                                                            | 설명                                                                                         | 기본값      | 키                            |
      | ------------------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | -------- | ---------------------------- |
      | `setOption(String key, String value)`                                     | `key` - 구성 옵션 키<br />`value` - 옵션 값                           | 클라이언트 옵션의 원시값을 설정합니다. 속성 파일에서 구성을 읽어올 때 유용합니다.                                             | -        | -                            |
      | `useAsyncRequests(boolean async)`                                         | `async` - 활성화/비활성화 플래그                                        | 클라이언트가 요청을 별도 스레드에서 실행할지 설정합니다. 멀티스레드 작업을 어떻게 구성할지는 애플리케이션이 더 잘 알고 있으므로 기본적으로 비활성화되어 있습니다. | `false`  | `async`                      |
      | `setSharedOperationExecutor(ExecutorService executorService)`             | `executorService` - ExecutorService 인스턴스                      | 작업 처리를 위한 ExecutorService를 설정합니다.                                                          | `none`   | `none`                       |
      | `setQueryIdGenerator(Supplier<String> supplier)`                          | `supplier` - 쿼리 ID를 생성하는 `Supplier<String>`                   | 작업 설정(`InsertSettings`, `QuerySettings`)에 쿼리 ID가 지정되지 않은 경우 사용할 사용자 지정 쿼리 ID 생성기를 설정합니다.   | -        | -                            |
      | `setClientNetworkBufferSize(int size)`                                    | `size` - 바이트 단위 크기                                            | 소켓과 애플리케이션 간에 데이터를 복사하는 데 사용하는 애플리케이션 메모리 공간의 버퍼 크기를 설정합니다.                                | `300000` | `client_network_buffer_size` |
      | `allowBinaryReaderToReuseBuffers(boolean reuse)`                          | `reuse` - 활성화/비활성화 플래그                                        | 활성화하면 리더가 숫자 트랜스코딩 시 미리 할당된 버퍼를 사용합니다. 숫자 데이터 처리 시 GC 부담을 줄여줍니다.                           | -        | -                            |
      | `columnToMethodMatchingStrategy(ColumnToMethodMatchingStrategy strategy)` | `strategy` - 매칭 전략 구현                                         | DTO 등록 시 DTO 클래스 필드와 DB 컬럼을 매칭하는 데 사용할 사용자 지정 전략을 설정합니다.                                   | `none`   | `none`                       |
      | `setClientName(String clientName)`                                        | `clientName` - 애플리케이션 이름 문자열                                  | 호출하는 애플리케이션에 대한 추가 정보를 설정합니다. `User-Agent` 헤더로 전달됩니다.                                      | -        | `client_name`                |
      | `registerClientMetrics(Object registry, String name)`                     | `registry` - Micrometer registry 인스턴스<br />`name` - 메트릭 그룹 이름 | Micrometer([https://micrometer.io/](https://micrometer.io/)) registry 인스턴스에 센서를 등록합니다.     | -        | -                            |
      | `setServerVersion(String version)`                                        | `version` - 서버 버전 문자열                                         | 버전 감지를 건너뛰도록 서버 버전을 설정합니다.                                                                 | -        | `server_version`             |
      | `typeHintMapping(Map typeHintMapping)`                                    | `typeHintMapping` - 타입 힌트 맵                                   | ClickHouse 타입에 대한 타입 힌트 매핑을 설정합니다. 예를 들어 다차원 배열이 Java 컨테이너로 표현되도록 할 수 있습니다.                | -        | `type_hint_mapping`          |
    </Tab>
  </Tabs>

  <br />

  ### 클라이언트 식별

  쿼리 로그에는 요청을 발생시킨 애플리케이션을 식별하는 두 필드가 있습니다: `client_name`과 `http_user_agent`. 네이티브 TCP 프로토콜은 애플리케이션을 식별하기 위해 `client_name`을 사용하고, HTTP 프로토콜은 `http_user_agent`를 사용합니다. 클라이언트 빌더에는 두 프로토콜에 대해 올바른 값을 설정하는 `setClientName` 메서드가 있습니다.
  `http_user_agent` 필드는 `User-Agent` 헤더의 일반 형식인 `application-name[/version] [(operating-system; architecture; ...)]`에 따라 설정됩니다.
  이 값 집합은 애플리케이션, 클라이언트 라이브러리, HTTP 클라이언트 라이브러리 등 각 계층마다 반복됩니다. `setClientName` 메서드로 설정한 값이 목록의 맨 앞에 옵니다.

  예시:

  ```java showLineNumbers theme={null}
  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_id`와 `log_comment`라는 두 개의 필드가 더 있습니다.

  `query_id`는 작업의 고유 식별자입니다. `QuerySettings` 클래스의 `setQueryId` 메서드를 호출하면 애플리케이션에서 직접 설정할 수 있습니다.

  ```java showLineNumbers theme={null}
  QuerySettings querySettings = new QuerySettings();
  querySettings.setQueryId("some-query-id");
  ```

  `log_comment`은 쿼리 로그에 추가할 수 있는 주석입니다. `QuerySettings` 클래스의 `logComment` 메서드를 호출하면 애플리케이션에서 설정할 수 있습니다.

  ```java showLineNumbers theme={null}
  QuerySettings querySettings = new QuerySettings();
  querySettings.logComment("some-comment");
  ```

  ### 서버 설정

  서버 측 설정은 클라이언트 생성 시 클라이언트 수준에서 한 번 지정하거나(`Builder`의 `serverSetting` 메서드 참조), 작업 수준에서도 지정할 수 있습니다(작업 설정 클래스의 `serverSetting` 참조).

  ```java showLineNumbers theme={null}
  try (Client client = new Client.Builder().addEndpoint(Protocol.HTTP, "localhost", mockServer.port(), false)
          .setUsername("default")
          .setPassword(ClickHouseServerForTest.getPassword())
          .compressClientRequest(true)

          // 클라이언트 수준
          .serverSetting("max_threads", "10")
          .serverSetting("async_insert", "1")
          .serverSetting("roles", Arrays.asList("role1", "role2"))

          .build()) {

  	// 작업 수준
  	QuerySettings querySettings = new QuerySettings();
  	querySettings.serverSetting("session_timezone", "Europe/Zurich");

  	...
  }
  ```

  ⚠️ `setOption` 메서드(`Client.Builder` 또는 작업 설정 클래스)를 통해 옵션을 설정하는 경우, 서버 설정 이름 앞에 `clickhouse_setting_`을 접두사로 추가해야 합니다. 이 경우 `com.clickhouse.client.api.ClientConfigProperties#serverSetting()`을 사용하면 편리합니다.

  ### 사용자 지정 HTTP 헤더

  사용자 정의 HTTP headers는 모든 작업(클라이언트 수준) 또는 개별 작업(작업 수준)에 설정할 수 있습니다.

  ```java showLineNumbers theme={null}
  QuerySettings settings = new QuerySettings()
      .httpHeader(HttpHeaders.REFERER, clientReferer)
      .setQueryId(qId);
  ```

  `setOption` 메서드(`Client.Builder` 또는 작업 설정 클래스)를 통해 옵션을 설정하는 경우, 사용자 지정 헤더 이름에는 `http_header_` 접두사를 붙여야 합니다. 이 경우 `com.clickhouse.client.api.ClientConfigProperties#httpHeader()` 메서드를 사용하면 편리할 수 있습니다.

  ## 공통 정의

  ### ClickHouseFormat

  [지원되는 포맷](/ko/reference/formats)의 열거형(Enum)입니다. ClickHouse가 지원하는 모든 포맷을 포함합니다.

  * `raw` - raw 데이터는 사용자가 직접 트랜스코딩해야 합니다
  * `full` - 클라이언트가 직접 데이터를 트랜스코딩할 수 있으며, 원시 데이터 스트림을 수신합니다
  * `-` - 이 포맷에서는 ClickHouse가 해당 작업을 지원하지 않습니다

  이 클라이언트 버전에서 지원하는 기능은 다음과 같습니다:

  | 포맷                                                                                                                  |  입력  |  출력  |
  | ------------------------------------------------------------------------------------------------------------------- | :--: | :--: |
  | [TabSeparated](/ko/reference/formats/TabSeparated/TabSeparated)                                                     |  raw |  raw |
  | [TabSeparatedRaw](/ko/reference/formats/TabSeparated/TabSeparatedRaw)                                               |  raw |  raw |
  | [TabSeparatedWithNames](/ko/reference/formats/TabSeparated/TabSeparatedWithNames)                                   |  raw |  raw |
  | [TabSeparatedWithNamesAndTypes](/ko/reference/formats/TabSeparated/TabSeparatedWithNamesAndTypes)                   |  raw |  raw |
  | [TabSeparatedRawWithNames](/ko/reference/formats/TabSeparated/TabSeparatedRawWithNames)                             |  raw |  raw |
  | [TabSeparatedRawWithNamesAndTypes](/ko/reference/formats/TabSeparated/TabSeparatedRawWithNamesAndTypes)             |  raw |  raw |
  | [Template](/ko/reference/formats/Template/Template)                                                                 |  raw |  raw |
  | [TemplateIgnoreSpaces](/ko/reference/formats/Template/TemplateIgnoreSpaces)                                         |  raw |   -  |
  | [CSV](/ko/reference/formats/CSV/CSV)                                                                                |  raw |  raw |
  | [CSVWithNames](/ko/reference/formats/CSV/CSVWithNames)                                                              |  raw |  raw |
  | [CSVWithNamesAndTypes](/ko/reference/formats/CSV/CSVWithNamesAndTypes)                                              |  raw |  raw |
  | [CustomSeparated](/ko/reference/formats/CustomSeparated/CustomSeparated)                                            |  raw |  raw |
  | [CustomSeparatedWithNames](/ko/reference/formats/CustomSeparated/CustomSeparatedWithNames)                          |  raw |  raw |
  | [CustomSeparatedWithNamesAndTypes](/ko/reference/formats/CustomSeparated/CustomSeparatedWithNamesAndTypes)          |  raw |  raw |
  | [SQLInsert](/ko/reference/formats/SQLInsert)                                                                        |   -  |  raw |
  | [Values](/ko/reference/formats/Values)                                                                              |  raw |  raw |
  | [Vertical](/ko/reference/formats/Vertical)                                                                          |   -  |  raw |
  | [JSON](/ko/reference/formats/JSON/JSON)                                                                             |  raw |  raw |
  | [JSONAsString](/ko/reference/formats/JSON/JSONAsString)                                                             |  raw |   -  |
  | [JSONAsObject](/ko/reference/formats/JSON/JSONAsObject)                                                             |  raw |   -  |
  | [JSONStrings](/ko/reference/formats/JSON/JSONStrings)                                                               |  raw |  raw |
  | [JSONColumns](/ko/reference/formats/JSON/JSONColumns)                                                               |  raw |  raw |
  | [JSONColumnsWithMetadata](/ko/reference/formats/JSON/JSONColumnsWithMetadata)                                       |  raw |  raw |
  | [JSONCompact](/ko/reference/formats/JSON/JSONCompact)                                                               |  raw |  raw |
  | [JSONCompactStrings](/ko/reference/formats/JSON/JSONCompactStrings)                                                 |   -  |  raw |
  | [JSONCompactColumns](/ko/reference/formats/JSON/JSONCompactColumns)                                                 |  raw |  raw |
  | [JSONEachRow](/ko/reference/formats/JSON/JSONEachRow)                                                               |  raw |  raw |
  | [PrettyJSONEachRow](/ko/reference/formats/JSON/PrettyJSONEachRow)                                                   |   -  |  raw |
  | [JSONEachRowWithProgress](/ko/reference/formats/JSON/JSONEachRowWithProgress)                                       |   -  |  raw |
  | [JSONStringsEachRow](/ko/reference/formats/JSON/JSONStringsEachRow)                                                 |  raw |  raw |
  | [JSONStringsEachRowWithProgress](/ko/reference/formats/JSON/JSONStringsEachRowWithProgress)                         |   -  |  raw |
  | [JSONCompactEachRow](/ko/reference/formats/JSON/JSONCompactEachRow)                                                 |  raw |  raw |
  | [JSONCompactEachRowWithNames](/ko/reference/formats/JSON/JSONCompactEachRowWithNames)                               |  raw |  raw |
  | [JSONCompactEachRowWithNamesAndTypes](/ko/reference/formats/JSON/JSONCompactEachRowWithNamesAndTypes)               |  raw |  raw |
  | [JSONCompactStringsEachRow](/ko/reference/formats/JSON/JSONCompactStringsEachRow)                                   |  raw |  raw |
  | [JSONCompactStringsEachRowWithNames](/ko/reference/formats/JSON/JSONCompactStringsEachRowWithNames)                 |  raw |  raw |
  | [JSONCompactStringsEachRowWithNamesAndTypes](/ko/reference/formats/JSON/JSONCompactStringsEachRowWithNamesAndTypes) |  raw |  raw |
  | [JSONObjectEachRow](/ko/reference/formats/JSON/JSONObjectEachRow)                                                   |  raw |  raw |
  | [BSONEachRow](/ko/reference/formats/BSONEachRow)                                                                    |  raw |  raw |
  | [TSKV](/ko/reference/formats/TabSeparated/TSKV)                                                                     |  raw |  raw |
  | [Pretty](/ko/reference/formats/Pretty/Pretty)                                                                       |   -  |  raw |
  | [PrettyNoEscapes](/ko/reference/formats/Pretty/PrettyNoEscapes)                                                     |   -  |  raw |
  | [PrettyMonoBlock](/ko/reference/formats/Pretty/PrettyMonoBlock)                                                     |   -  |  raw |
  | [PrettyNoEscapesMonoBlock](/ko/reference/formats/Pretty/PrettyNoEscapesMonoBlock)                                   |   -  |  raw |
  | [PrettyCompact](/ko/reference/formats/Pretty/PrettyCompact)                                                         |   -  |  raw |
  | [PrettyCompactNoEscapes](/ko/reference/formats/Pretty/PrettyCompactNoEscapes)                                       |   -  |  raw |
  | [PrettyCompactMonoBlock](/ko/reference/formats/Pretty/PrettyCompactMonoBlock)                                       |   -  |  raw |
  | [PrettyCompactNoEscapesMonoBlock](/ko/reference/formats/Pretty/PrettyCompactNoEscapesMonoBlock)                     |   -  |  raw |
  | [PrettySpace](/ko/reference/formats/Pretty/PrettySpace)                                                             |   -  |  raw |
  | [PrettySpaceNoEscapes](/ko/reference/formats/Pretty/PrettySpaceNoEscapes)                                           |   -  |  raw |
  | [PrettySpaceMonoBlock](/ko/reference/formats/Pretty/PrettySpaceMonoBlock)                                           |   -  |  raw |
  | [PrettySpaceNoEscapesMonoBlock](/ko/reference/formats/Pretty/PrettySpaceNoEscapesMonoBlock)                         |   -  |  raw |
  | [Prometheus](/ko/reference/formats/Prometheus)                                                                      |   -  |  raw |
  | [Protobuf](/ko/reference/formats/Protobuf/Protobuf)                                                                 |  raw |  raw |
  | [ProtobufSingle](/ko/reference/formats/Protobuf/ProtobufSingle)                                                     |  raw |  raw |
  | [ProtobufList](/ko/reference/formats/Protobuf/ProtobufList)                                                         |  raw |  raw |
  | [Avro](/ko/reference/formats/Avro/Avro)                                                                             |  raw |  raw |
  | [AvroConfluent](/ko/reference/formats/Avro/AvroConfluent)                                                           |  raw |   -  |
  | [Parquet](/ko/reference/formats/Parquet/Parquet)                                                                    |  raw |  raw |
  | [ParquetMetadata](/ko/reference/formats/Parquet/ParquetMetadata)                                                    |  raw |   -  |
  | [Arrow](/ko/reference/formats/Arrow/Arrow)                                                                          |  raw |  raw |
  | [ArrowStream](/ko/reference/formats/Arrow/ArrowStream)                                                              |  raw |  raw |
  | [ORC](/ko/reference/formats/ORC)                                                                                    |  raw |  raw |
  | [One](/ko/reference/formats/One)                                                                                    |  raw |   -  |
  | [Npy](/ko/reference/formats/Npy)                                                                                    |  raw |  raw |
  | [RowBinary](/ko/reference/formats/RowBinary/RowBinary)                                                              | full | full |
  | [RowBinaryWithNames](/ko/reference/formats/RowBinary/RowBinaryWithNamesAndTypes)                                    | full | full |
  | [RowBinaryWithNamesAndTypes](/ko/reference/formats/RowBinary/RowBinaryWithNamesAndTypes)                            | full | full |
  | [RowBinaryWithDefaults](/ko/reference/formats/RowBinary/RowBinaryWithDefaults)                                      | full |   -  |
  | [Native](/ko/reference/formats/Native)                                                                              | full |  raw |
  | [Null](/ko/reference/formats/Null)                                                                                  |   -  |  raw |
  | [XML](/ko/reference/formats/XML)                                                                                    |   -  |  raw |
  | [CapnProto](/ko/reference/formats/CapnProto)                                                                        |  raw |  raw |
  | [LineAsString](/ko/reference/formats/LineAsString/LineAsString)                                                     |  raw |  raw |
  | [Regexp](/ko/reference/formats/Regexp)                                                                              |  raw |   -  |
  | [RawBLOB](/ko/reference/formats/RawBLOB)                                                                            |  raw |  raw |
  | [MsgPack](/ko/reference/formats/MsgPack)                                                                            |  raw |  raw |
  | [MySQLDump](/ko/reference/formats/MySQLDump)                                                                        |  raw |   -  |
  | [DWARF](/ko/reference/formats/DWARF)                                                                                |  raw |   -  |
  | [Markdown](/ko/reference/formats/Markdown)                                                                          |   -  |  raw |
  | [Form](/ko/reference/formats/Form)                                                                                  |  raw |   -  |

  ## 삽입 API

  ### insert(String tableName, InputStream data, ClickHouseFormat format)

  지정된 포맷으로 바이트의 `InputStream` 형태로 데이터를 받습니다. `data`는 `format`으로 인코딩되어 있어야 합니다.

  **서명**

  ```java theme={null}
  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 - 작업 결과와 서버 측 메트릭 등의 추가 정보입니다.

  **예시**

  ```java showLineNumbers theme={null}
  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)` 메서드를 사용해 사전에 등록해야 합니다.

  **서명**

  ```java theme={null}
  client.insert(String tableName, List<?> data, InsertSettings settings)
  client.insert(String tableName, List<?> data)
  ```

  **매개변수**

  `tableName` - 대상 테이블의 이름입니다.

  `data` - 컬렉션 DTO(Data Transfer Object) 객체.

  `settings` - 요청 설정입니다.

  **반환값**

  `InsertResponse` 유형의 Future로, 작업 결과 및 서버 측 메트릭 등의 추가 정보를 포함합니다.

  **예시**

  ```java showLineNumbers theme={null}
  // 중요한 단계 (한 번만 수행) - 테이블 스키마에 따라 객체 직렬화기를 사전 컴파일하도록 클래스를 등록합니다.
  client.register(ArticleViewEvent.class, client.getTableSchema(TABLE_NAME));

  List<ArticleViewEvent> events = loadBatch();

  try (InsertResponse response = client.insert(TABLE_NAME, events).get()) {
      // 응답을 처리한 후 닫히며, 요청을 처리한 연결이 해제됩니다.
  }
  ```

  ### 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)`        | raw 포맷으로 구성 옵션을 지정합니다. 이것은 서버 설정이 아닙니다.                                             |

  ### InsertResponse

  삽입 작업의 결과를 담는 응답 객체입니다. 클라이언트가 서버로부터 응답을 받은 경우에만 사용 가능합니다.

  <Note>
    이 객체는 연결을 해제하기 위해 가능한 한 빨리 닫아야 합니다. 이전 응답의 데이터를 모두 완전히 읽기 전까지는 해당 연결을 재사용할 수 없기 때문입니다.
  </Note>

  | 메서드                             | 설명                                                    |
  | ------------------------------- | ----------------------------------------------------- |
  | `OperationMetrics getMetrics()` | 작업 메트릭이 포함된 객체를 반환합니다.                                |
  | `String getQueryId()`           | 애플리케이션이 작업 설정을 통해 또는 server가 작업에 할당한 Query id를 반환합니다. |

  ## 쿼리 API

  ### query(String sqlQuery)

  `sqlQuery`를 그대로 전송합니다. 응답 포맷은 쿼리 설정에 따라 결정됩니다. `QueryResponse`는 해당 포맷을 지원하는 리더(reader)가 읽어야 하는 응답 스트림에 대한 참조를 보유합니다.

  **서명**

  ```java theme={null}
  CompletableFuture<QueryResponse> query(String sqlQuery, QuerySettings settings)
  CompletableFuture<QueryResponse> query(String sqlQuery)
  ```

  **매개변수**

  `sqlQuery` - 단일 SQL 구문입니다. 쿼리는 수정 없이 그대로 서버로 전송됩니다.

  `settings` - 요청 설정.

  **반환 값**

  `QueryResponse` 유형의 Future - 결과 데이터셋과 서버 측 메트릭 등의 추가 정보를 포함합니다. 데이터셋을 모두 사용한 후에는 Response 객체를 닫아야 합니다.

  **예시**

  ```java theme={null}
  final String sql = "select * from " + TABLE_NAME + " where title <> '' limit 10";

  // 기본 포맷은 RowBinaryWithNamesAndTypesFormatReader이므로 reader가 컬럼에 대한 모든 정보를 가집니다
  try (QueryResponse response = client.query(sql).get(3, TimeUnit.SECONDS);) {

      // 데이터에 편리하게 접근하기 위한 reader를 생성합니다
      ClickHouseBinaryFormatReader reader = client.newBinaryFormatReader(response);

      while (reader.hasNext()) {
          reader.next(); // 스트림에서 다음 레코드를 읽고 파싱합니다

          // 값 가져오기
          double id = reader.getDouble("id");
          String title = reader.getString("title");
          String url = reader.getString("url");

          // 데이터 수집
      }
  } catch (Exception e) {
      log.error("Failed to read data", e);
  }

  // HTTP connection을 최대한 빨리 해제하려면 비즈니스 로직을 읽기 블록 외부에 작성하십시오.
  ```

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

  `sqlQuery`를 그대로 전송합니다. 또한 서버가 SQL 표현식을 컴파일할 수 있도록 쿼리 매개변수도 함께 전송합니다.

  **시그니처**

  ```java theme={null}
  CompletableFuture<QueryResponse> query(String sqlQuery, Map<String, Object> queryParams, QuerySettings settings)
  ```

  **매개변수**

  `sqlQuery` - 자리 표시자 `{}`가 포함된 SQL 표현식입니다.

  `queryParams` - 서버에서 SQL 표현식을 완성하는 데 사용되는 변수들의 맵입니다.

  `settings` - 요청 설정입니다.

  **반환 값**

  `QueryResponse` 유형의 Future로, 결과 데이터셋과 서버 측 메트릭 등의 추가 정보를 포함합니다. Response 객체는 데이터셋을 사용한 후 반드시 닫아야 합니다.

  **예시**

  ```java showLineNumbers theme={null}
  // 매개변수를 정의합니다. 요청과 함께 서버로 전송됩니다.
  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()) {

      // 데이터에 편리하게 접근하기 위한 리더를 생성합니다.
      ClickHouseBinaryFormatReader reader = client.newBinaryFormatReader(response);

      while (reader.hasNext()) {
          reader.next(); // 스트림에서 다음 레코드를 읽고 파싱합니다.

          // 데이터 읽기
      }

  } catch (Exception e) {
      log.error("데이터 읽기 실패", e);
  }
  ```

  ### queryAll(String sqlQuery)

  `RowBinaryWithNamesAndTypes` 포맷으로 데이터를 쿼리합니다. 결과를 컬렉션으로 반환합니다. 읽기 성능은 reader와 동일하지만, 전체 데이터셋을 메모리에 유지해야 하므로 더 많은 메모리가 필요합니다.

  **시그니처**

  ```java theme={null}
  List<GenericRecord> queryAll(String sqlQuery)
  ```

  **매개변수**

  `sqlQuery` - 서버에서 데이터를 쿼리하기 위한 SQL 표현식입니다.

  **반환 값**

  결과 데이터에 행(row) 방식으로 접근할 수 있는 `GenericRecord` 객체 목록으로 표현된 전체 데이터셋입니다.

  **예시**

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

      // 전체 결과 집합(result set)을 읽고 레코드를 하나씩 처리합니다
      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)`                      | 작업에 할당할 Query ID를 설정합니다.                                                                                                           |
  | `setFormat(ClickHouseFormat format)`              | 응답 포맷을 설정합니다. 전체 목록은 `RowBinaryWithNamesAndTypes`를 참조하세요.                                                                          |
  | `setMaxExecutionTime(Integer maxExecutionTime)`   | 서버에서의 작업 실행 시간을 설정합니다. 읽기 타임아웃에는 영향을 주지 않습니다.                                                                                      |
  | `waitEndOfQuery(Boolean waitEndOfQuery)`          | 응답을 보내기 전에 서버가 쿼리가 끝날 때까지 기다리도록 요청합니다.                                                                                             |
  | `setUseServerTimeZone(Boolean useServerTimeZone)` | 연산 결과의 날짜/시간 타입을 파싱할 때 서버 시간대(클라이언트 구성 참조)를 사용합니다. 기본값은 `false`입니다.                                                                |
  | `setUseTimeZone(String timeZone)`                 | `timeZone`을 시간 변환에 사용하도록 서버에 요청합니다. 자세한 내용은 [session\_timezone](/ko/reference/settings/session-settings#session_timezone)을 참조하십시오. |
  | `serverSetting(String name, String value)`        | 작업에 대한 개별 서버 설정을 지정합니다.                                                                                                            |
  | `serverSetting(String name, Collection values)`   | 작업에 사용할 개별 서버 설정을 여러 값으로 지정합니다. 컬렉션의 항목은 `String` 값이어야 합니다.                                                                        |
  | `setDBRoles(Collection dbRoles)`                  | 작업을 실행하기 전에 적용할 DB 역할을 설정합니다. 컬렉션의 항목은 `String` 값이어야 합니다.                                                                          |
  | `setOption(String option, Object value)`          | 구성 옵션을 원시 포맷으로 설정합니다. 서버 설정은 아닙니다.                                                                                                 |

  ### QueryResponse

  쿼리 실행 결과를 담는 응답 객체입니다. 클라이언트가 서버로부터 응답을 받은 경우에만 사용할 수 있습니다.

  <Note>
    이 객체는 연결을 반환할 수 있도록 가능한 한 빨리 닫아야 합니다. 이전 응답의 데이터를 모두 끝까지 읽기 전에는 해당 연결을 재사용할 수 없기 때문입니다.
  </Note>

  | 메서드                             | 설명                                                 |
  | ------------------------------- | -------------------------------------------------- |
  | `ClickHouseFormat getFormat()`  | 응답 데이터가 인코딩되는 포맷을 반환합니다.                           |
  | `InputStream getInputStream()`  | 지정된 포맷의 데이터에 대한 비압축 바이트 스트림을 반환합니다.                |
  | `OperationMetrics getMetrics()` | 작업 메트릭을 담은 객체를 반환합니다.                              |
  | `String getQueryId()`           | 애플리케이션이 작업에 할당한 쿼리 ID(작업 설정 또는 서버를 통해 할당됨)를 반환합니다. |
  | `TimeZone getTimeZone()`        | 응답에서 Date/DateTime 타입을 처리할 때 사용해야 하는 시간대를 반환합니다.   |

  ### 예시

  * 예시 코드는 [repo](https://github.com/ClickHouse/clickhouse-java/tree/main/examples/client-v2)에서 확인할 수 있습니다
  * Spring 서비스 [구현 예시](https://github.com/ClickHouse/clickhouse-java/tree/main/examples/demo-service) 참고

  ## 공통 API

  ### getTableSchema(String table)

  `table`의 테이블 스키마(schema)를 가져옵니다.

  **서명**

  ```java theme={null}
  TableSchema getTableSchema(String table)
  TableSchema getTableSchema(String table, String database)
  ```

  **매개변수**

  `table` - 스키마 데이터를 가져올 테이블 이름입니다.

  `database` - 대상 테이블이 정의된 데이터베이스입니다.

  **반환값**

  테이블 컬럼 목록이 담긴 `TableSchema` 객체를 반환합니다.

  ### getTableSchemaFromQuery(String sql)

  SQL 구문(statement)에서 스키마(schema)를 가져옵니다.

  **서명**

  ```java theme={null}
  TableSchema getTableSchemaFromQuery(String sql)
  ```

  **매개변수**

  `sql` - 스키마를 반환할 "SELECT" SQL 문입니다.

  **반환값**

  `sql` 표현식에 맞는 컬럼이 포함된 `TableSchema` 객체를 반환합니다.

  ### TableSchema

  ### register(Class\<?> clazz, TableSchema schema)

  `schema`를 사용하여 데이터를 쓰고 읽기 위한 Java 클래스의 직렬화(serialization) 및 역직렬화(deserialization) 레이어를 컴파일합니다. 이 메서드는 getter/setter 쌍과 해당 컬럼에 대한 직렬화기 및 역직렬화기를 생성합니다.
  컬럼 매칭은 메서드 이름에서 컬럼 이름을 추출하는 방식으로 수행됩니다. 예를 들어, `getFirstName`은 컬럼 `first_name` 또는 `firstname`에 해당합니다.

  **시그니처**

  ```java theme={null}
  void register(Class<?> clazz, TableSchema schema)
  ```

  **매개변수**

  `clazz` - 데이터를 읽고 쓰는 데 사용되는 POJO를 나타내는 클래스입니다.

  `schema` - POJO 속성과 매칭하는 데 사용하는 데이터 스키마입니다.

  **예시**

  ```java showLineNumbers theme={null}
  client.register(ArticleViewEvent.class, client.getTableSchema(TABLE_NAME));
  ```

  ## 사용 예시

  전체 예시 코드는 저장소의 'example\` [폴더](https://github.com/ClickHouse/clickhouse-java/tree/main/examples)에서 확인할 수 있습니다:

  * [client-v2](https://github.com/ClickHouse/clickhouse-java/tree/main/examples/client-v2) - 주요 예시 모음.
  * [demo-service](https://github.com/ClickHouse/clickhouse-java/tree/main/examples/demo-service) - Spring Boot 애플리케이션에서 클라이언트를 사용하는 방법을 보여주는 예시입니다.
  * [demo-kotlin-service](https://github.com/ClickHouse/clickhouse-java/tree/main/examples/demo-kotlin-service) - Ktor(Kotlin) 애플리케이션에서 클라이언트를 사용하는 방법을 보여주는 예시입니다.

  ## 데이터 읽기

  데이터를 읽는 일반적인 방법은 두 가지입니다:

  * 데이터가 포함된 `InputStream`을 담은 저수준 `QueryResponse` 객체를 반환하는 `query()` 메서드입니다. 일반적으로 스트리밍 읽기를 위해 `ClickHouseBinaryFormatReader`와 함께 사용되지만
    다른 사용자 지정 리더 구현에서도 사용할 수 있습니다. `QueryResponse`는 결과 집합 메타데이터와 메트릭에도 접근할 수 있게 해줍니다.
  * `queryAll()` 메서드와 `GenericRecord`를 사용하면 행에 더 편리하게 접근할 수 있습니다. 이 경우 전체 결과 세트가 메모리에 로드됩니다.
  * `queryRecords()` 메서드는 `GenericRecord` 객체를 위한 반복자인 `com.clickhouse.client.api.query.Records`를 반환합니다. 이 메서드는 스트리밍 방식을 사용하므로
    (데이터를 메모리에 로드하지 않음) `GenericRecord`를 통해 데이터에 접근합니다.

  **참고:** 스트리밍 방식은 데이터를 네트워크 스트림에서 직접 읽으므로, 읽기 속도가 충분히 빠르지 않으면 서버 쓰기 timeout이 발생할 수 있습니다.

  ### 배열 읽기

  **`ClickHouseBinaryFormatReader` 메서드**

  * `getList(...)` - 모든 `Array(...)`를 `List<T>`로 읽습니다. 타입이 유연한 읽기에 적합한 기본 옵션입니다. 중첩 배열을 지원합니다.
  * `getByteArray(...)`, `getShortArray(...)`, `getIntArray(...)`, `getLongArray(...)`, `getFloatArray(...)`, `getDoubleArray(...)`, `getBooleanArray(...)` - 기본형과 호환되는 값으로 구성된 1차원 배열에 가장 적합합니다.
  * `getStringArray(...)` - `Array(String)`용(이름으로 표현된 enum 값 포함).
  * `getObjectArray(...)` - 중첩 배열을 포함한 모든 `Array(...)` 타입의 요소에 사용할 수 있는 범용 옵션입니다. 널 허용 값을 포함하는 배열과 중첩 배열을 읽을 때 사용합니다.

  모든 메서드에 대해 인덱스 기반 및 이름 기반 오버로드를 사용할 수 있습니다. 인덱스는 1부터 시작합니다. 인덱스 기반 방식은 컬럼에 직접 접근합니다.
  이름 기반 메서드는 호출할 때마다 인덱스 조회가 필요합니다.

  ```java theme={null}
  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[]

          // 중첩 배열은 중첩된 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(...)` 요소 타입에 사용할 수 있는 범용 옵션입니다. 널 허용 값을 포함하는 배열과 중첩 배열을 읽는 데 사용합니다.

  모든 메서드에 대해 인덱스 기반 및 이름 기반 오버로드를 사용할 수 있습니다. 인덱스는 1부터 시작합니다. 인덱스 기반 방식은 컬럼에 직접 접근합니다.
  이름 기반 메서드는 호출할 때마다 인덱스 조회가 필요합니다.

  ```java theme={null}
  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`는 향후 다양한 구현을 지원하기 위한 파사드 클래스입니다.
  * 구성 소스 수가 더 적습니다. 하나는 빌더에 제공되고, 다른 하나는 작업 설정(`QuerySettings`, `InsertSettings`)에 있습니다. 이전 버전에서는 노드별 구성을 사용했고, 경우에 따라 환경 변수도 불러왔습니다.

  ### 구성 매개변수 일치

  V1에는 구성과 관련된 enum 클래스가 3개 있습니다:

  * `com.clickhouse.client.config.ClickHouseDefaults` - 대부분의 사용 사례에서 설정해야 하는 구성 매개변수입니다. 예를 들어 `USER` 및 `PASSWORD`가 있습니다.
  * `com.clickhouse.client.config.ClickHouseClientOption` - 클라이언트 전용 구성 매개변수입니다. 예: `HEALTH_CHECK_INTERVAL`.
  * `com.clickhouse.client.http.config.ClickHouseHttpOption` - HTTP 인터페이스 전용 구성 매개변수입니다. 예: `RECEIVE_QUERY_PROGRESS`.

  이는 매개변수를 그룹화하고 명확한 구분을 제공하기 위해 설계되었습니다. 그러나 일부 경우에는 혼란을 야기하기도 했습니다(`com.clickhouse.client.config.ClickHouseDefaults#ASYNC`와
  `com.clickhouse.client.config.ClickHouseClientOption#ASYNC` 간에 차이가 있는지 불분명한 경우 등). 새로운 V2 클라이언트는 `com.clickhouse.client.api.Client.Builder`를 가능한 모든 클라이언트 구성 옵션의 단일 딕셔너리로 사용합니다. 모든 구성 매개변수 이름은
  `com.clickhouse.client.api.ClientConfigProperties`에 나열되어 있습니다.

  아래 표에서는 새 클라이언트에서 지원되는 기존 옵션과 해당 옵션의 새로운 의미를 확인할 수 있습니다.

  **범례:** ✔ = 지원됨, ✗ = 삭제됨

  <Tabs>
    <Tab title="연결 및 인증">
      | V1 구성                                                                            | V2 Builder 메서드                              | 비고              |
      | -------------------------------------------------------------------------------- | ------------------------------------------- | --------------- |
      | `ClickHouseDefaults#HOST`                                                        | `Client.Builder#addEndpoint`                |                 |
      | `ClickHouseDefaults#PROTOCOL`                                                    | ✗                                           | V2는 HTTP만 지원합니다 |
      | `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`           |                 |
    </Tab>

    <Tab title="SSL 및 보안">
      | V1 구성                                                  | V2 빌더 메서드                                 | 비고                                               |
      | ------------------------------------------------------ | ----------------------------------------- | ------------------------------------------------ |
      | `ClickHouseDefaults#SSL_CERTIFICATE_TYPE`              | ✗                                         |                                                  |
      | `ClickHouseDefaults#SSL_KEY_ALGORITHM`                 | ✗                                         |                                                  |
      | `ClickHouseDefaults#SSL_PROTOCOL`                      | ✗                                         |                                                  |
      | `ClickHouseClientOption#SSL`                           | ✗                                         | `Client.Builder#addEndpoint` 참조                  |
      | `ClickHouseClientOption#SSL_MODE`                      | ✗                                         |                                                  |
      | `ClickHouseClientOption#SSL_ROOT_CERTIFICATE`          | `Client.Builder#setRootCertificate`       | SSL 인증은 `useSSLAuthentication`으로 활성화해야 합니다       |
      | `ClickHouseClientOption#SSL_CERTIFICATE`               | `Client.Builder#setClientCertificate`     |                                                  |
      | `ClickHouseClientOption#SSL_KEY`                       | `Client.Builder#setClientKey`             |                                                  |
      | `ClickHouseClientOption#KEY_STORE_TYPE`                | `Client.Builder#setSSLTrustStoreType`     |                                                  |
      | `ClickHouseClientOption#TRUST_STORE`                   | `Client.Builder#setSSLTrustStore`         |                                                  |
      | `ClickHouseClientOption#KEY_STORE_PASSWORD`            | `Client.Builder#setSSLTrustStorePassword` |                                                  |
      | `ClickHouseClientOption#SSL_SOCKET_SNI`                | `Client.Builder#sslSocketSNI`             |                                                  |
      | `ClickHouseClientOption#CUSTOM_SOCKET_FACTORY`         | ✗                                         |                                                  |
      | `ClickHouseClientOption#CUSTOM_SOCKET_FACTORY_OPTIONS` | ✗                                         | SNI를 설정하려면 `Client.Builder#sslSocketSNI`를 참조하십시오 |
    </Tab>

    <Tab title="소켓 옵션">
      | V1 구성                                       | V2 빌더 메서드                              | 비고 |
      | ------------------------------------------- | -------------------------------------- | -- |
      | `ClickHouseClientOption#SOCKET_TIMEOUT`     | `Client.Builder#setSocketTimeout`      |    |
      | `ClickHouseClientOption#SOCKET_REUSEADDR`   | `Client.Builder#setSocketReuseAddress` |    |
      | `ClickHouseClientOption#SOCKET_KEEPALIVE`   | `Client.Builder#setSocketKeepAlive`    |    |
      | `ClickHouseClientOption#SOCKET_LINGER`      | `Client.Builder#setSocketLinger`       |    |
      | `ClickHouseClientOption#SOCKET_IP_TOS`      | ✗                                      |    |
      | `ClickHouseClientOption#SOCKET_TCP_NODELAY` | `Client.Builder#setSocketTcpNodelay`   |    |
      | `ClickHouseClientOption#SOCKET_RCVBUF`      | `Client.Builder#setSocketRcvbuf`       |    |
      | `ClickHouseClientOption#SOCKET_SNDBUF`      | `Client.Builder#setSocketSndbuf`       |    |
    </Tab>

    <Tab title="압축">
      | V1 구성                                         | V2 빌더 메서드                               | 비고                                                      |
      | --------------------------------------------- | --------------------------------------- | ------------------------------------------------------- |
      | `ClickHouseClientOption#COMPRESS`             | `Client.Builder#compressServerResponse` | 관련 항목: `useHttpCompression`                             |
      | `ClickHouseClientOption#DECOMPRESS`           | `Client.Builder#compressClientRequest`  | 관련 항목: `useHttpCompression`                             |
      | `ClickHouseClientOption#COMPRESS_ALGORITHM`   | ✗                                       | non-http는 `LZ4`를 사용합니다. Http는 `Accept-Encoding`을 사용합니다  |
      | `ClickHouseClientOption#DECOMPRESS_ALGORITHM` | ✗                                       | non-http는 `LZ4`를 사용합니다. Http는 `Content-Encoding`을 사용합니다 |
      | `ClickHouseClientOption#COMPRESS_LEVEL`       | ✗                                       |                                                         |
      | `ClickHouseClientOption#DECOMPRESS_LEVEL`     | ✗                                       |                                                         |
    </Tab>

    <Tab title="프록시">
      | V1 구성                                   | V2 빌더 메서드                            | 비고 |
      | --------------------------------------- | ------------------------------------ | -- |
      | `ClickHouseClientOption#PROXY_TYPE`     | `Client.Builder#addProxy`            |    |
      | `ClickHouseClientOption#PROXY_HOST`     | `Client.Builder#addProxy`            |    |
      | `ClickHouseClientOption#PROXY_PORT`     | `Client.Builder#addProxy`            |    |
      | `ClickHouseClientOption#PROXY_USERNAME` | `Client.Builder#setProxyCredentials` |    |
      | `ClickHouseClientOption#PROXY_PASSWORD` | `Client.Builder#setProxyCredentials` |    |
    </Tab>

    <Tab title="타임아웃 및 재시도">
      | V1 구성                                           | V2 빌더 메서드                            | 비고                       |
      | ----------------------------------------------- | ------------------------------------ | ------------------------ |
      | `ClickHouseClientOption#MAX_EXECUTION_TIME`     | `Client.Builder#setExecutionTimeout` |                          |
      | `ClickHouseClientOption#RETRY`                  | `Client.Builder#setMaxRetries`       | 관련 항목: `retryOnFailures` |
      | `ClickHouseHttpOption#AHC_RETRY_ON_FAILURE`     | `Client.Builder#retryOnFailures`     |                          |
      | `ClickHouseClientOption#FAILOVER`               | ✗                                    |                          |
      | `ClickHouseClientOption#REPEAT_ON_SESSION_LOCK` | ✗                                    |                          |
      | `ClickHouseClientOption#SESSION_ID`             | ✗                                    |                          |
      | `ClickHouseClientOption#SESSION_CHECK`          | ✗                                    |                          |
      | `ClickHouseClientOption#SESSION_TIMEOUT`        | ✗                                    |                          |
    </Tab>

    <Tab title="시간대">
      | V1 구성                                                                                | V2 빌더 메서드                          | 비고 |
      | ------------------------------------------------------------------------------------ | ---------------------------------- | -- |
      | `ClickHouseDefaults#SERVER_TIME_ZONE`<br />`ClickHouseClientOption#SERVER_TIME_ZONE` | `Client.Builder#setServerTimeZone` |    |
      | `ClickHouseClientOption#USE_SERVER_TIME_ZONE`                                        | `Client.Builder#useServerTimeZone` |    |
      | `ClickHouseClientOption#USE_SERVER_TIME_ZONE_FOR_DATES`                              |                                    |    |
      | `ClickHouseClientOption#USE_TIME_ZONE`                                               | `Client.Builder#useTimeZone`       |    |
    </Tab>

    <Tab title="버퍼 및 성능">
      | V1 구성                                           | V2 빌더 메서드                                   | 비고 |
      | ----------------------------------------------- | ------------------------------------------- | -- |
      | `ClickHouseClientOption#BUFFER_SIZE`            | `Client.Builder#setClientNetworkBufferSize` |    |
      | `ClickHouseClientOption#BUFFER_QUEUE_VARIATION` | ✗                                           |    |
      | `ClickHouseClientOption#READ_BUFFER_SIZE`       | ✗                                           |    |
      | `ClickHouseClientOption#WRITE_BUFFER_SIZE`      | ✗                                           |    |
      | `ClickHouseClientOption#REQUEST_CHUNK_SIZE`     | ✗                                           |    |
      | `ClickHouseClientOption#REQUEST_BUFFERING`      | ✗                                           |    |
      | `ClickHouseClientOption#RESPONSE_BUFFERING`     | ✗                                           |    |
      | `ClickHouseClientOption#MAX_BUFFER_SIZE`        | ✗                                           |    |
      | `ClickHouseClientOption#MAX_QUEUED_BUFFERS`     | ✗                                           |    |
      | `ClickHouseClientOption#MAX_QUEUED_REQUESTS`    | ✗                                           |    |
      | `ClickHouseClientOption#REUSE_VALUE_WRAPPER`    | ✗                                           |    |
    </Tab>

    <Tab title="스레딩 & 비동기">
      | V1 구성                                                          | V2 Builder 메서드                    | 비고                              |
      | -------------------------------------------------------------- | --------------------------------- | ------------------------------- |
      | `ClickHouseDefaults#ASYNC`<br />`ClickHouseClientOption#ASYNC` | `Client.Builder#useAsyncRequests` |                                 |
      | `ClickHouseDefaults#MAX_SCHEDULER_THREADS`                     | ✗                                 | `setSharedOperationExecutor` 참조 |
      | `ClickHouseDefaults#MAX_THREADS`                               | ✗                                 | `setSharedOperationExecutor` 참조 |
      | `ClickHouseDefaults#THREAD_KEEPALIVE_TIMEOUT`                  | `setSharedOperationExecutor` 참조   |                                 |
      | `ClickHouseClientOption#MAX_THREADS_PER_CLIENT`                | ✗                                 |                                 |
      | `ClickHouseClientOption#MAX_CORE_THREAD_TTL`                   | ✗                                 |                                 |
    </Tab>

    <Tab title="HTTP 및 헤더">
      | V1 구성                                                | V2 Builder 메서드                 | 비고                                |
      | ---------------------------------------------------- | ------------------------------ | --------------------------------- |
      | `ClickHouseHttpOption#CUSTOM_HEADERS`                | `Client.Builder#httpHeaders`   |                                   |
      | `ClickHouseHttpOption#CUSTOM_PARAMS`                 | ✗                              | `Client.Builder#serverSetting` 참조 |
      | `ClickHouseClientOption#CLIENT_NAME`                 | `Client.Builder#setClientName` |                                   |
      | `ClickHouseHttpOption#CONNECTION_PROVIDER`           | ✗                              |                                   |
      | `ClickHouseHttpOption#DEFAULT_RESPONSE`              | ✗                              |                                   |
      | `ClickHouseHttpOption#SEND_HTTP_CLIENT_ID`           | ✗                              |                                   |
      | `ClickHouseHttpOption#AHC_VALIDATE_AFTER_INACTIVITY` | ✗                              | Apache Http Client 사용 시 항상 활성화됩니다 |
    </Tab>

    <Tab title="포맷 및 쿼리">
      | V1 구성                                                            | V2 빌더 메서드           | 비고                                                                             |
      | ---------------------------------------------------------------- | ------------------- | ------------------------------------------------------------------------------ |
      | `ClickHouseDefaults#FORMAT`<br />`ClickHouseClientOption#FORMAT` | ✗                   | 작업 설정(`QuerySettings` 및 `InsertSettings`)으로 이동했습니다                             |
      | `ClickHouseClientOption#QUERY_ID`                                | ✗                   | `QuerySettings` 및 `InsertSettings`를 참조하십시오                                     |
      | `ClickHouseClientOption#LOG_LEADING_COMMENT`                     | ✗                   | `QuerySettings#logComment` 및 `InsertSettings#logComment`를 참조하십시오               |
      | `ClickHouseClientOption#MAX_RESULT_ROWS`                         | ✗                   | 서버 측 설정입니다                                                                     |
      | `ClickHouseClientOption#RESULT_OVERFLOW_MODE`                    | ✗                   | 서버 측 설정입니다                                                                     |
      | `ClickHouseHttpOption#RECEIVE_QUERY_PROGRESS`                    | ✗                   | 서버 측 설정입니다                                                                     |
      | `ClickHouseHttpOption#WAIT_END_OF_QUERY`                         | ✗                   | 서버 측 설정입니다                                                                     |
      | `ClickHouseHttpOption#REMEMBER_LAST_SET_ROLES`                   | `Client#setDBRoles` | 이제 런타임 구성입니다. `QuerySettings#setDBRoles` 및 `InsertSettings#setDBRoles`도 참조하십시오 |
    </Tab>

    <Tab title="노드 디스커버리 및 부하 분산">
      | V1 구성                                            | V2 빌더 메서드 | 비고 |
      | ------------------------------------------------ | --------- | -- |
      | `ClickHouseClientOption#AUTO_DISCOVERY`          | ✗         |    |
      | `ClickHouseClientOption#LOAD_BALANCING_POLICY`   | ✗         |    |
      | `ClickHouseClientOption#LOAD_BALANCING_TAGS`     | ✗         |    |
      | `ClickHouseClientOption#HEALTH_CHECK_INTERVAL`   | ✗         |    |
      | `ClickHouseClientOption#HEALTH_CHECK_METHOD`     | ✗         |    |
      | `ClickHouseClientOption#NODE_DISCOVERY_INTERVAL` | ✗         |    |
      | `ClickHouseClientOption#NODE_DISCOVERY_LIMIT`    | ✗         |    |
      | `ClickHouseClientOption#NODE_CHECK_INTERVAL`     | ✗         |    |
      | `ClickHouseClientOption#NODE_GROUP_SIZE`         | ✗         |    |
      | `ClickHouseClientOption#CHECK_ALL_NODES`         | ✗         |    |
    </Tab>

    <Tab title="기타">
      | V1 구성                                                                            | V2 빌더 메서드                         | 비고                  |
      | -------------------------------------------------------------------------------- | --------------------------------- | ------------------- |
      | `ClickHouseDefaults#AUTO_SESSION`                                                | ✗                                 | 세션 지원은 추후 검토될 예정입니다 |
      | `ClickHouseDefaults#BUFFERING`                                                   | ✗                                 |                     |
      | `ClickHouseDefaults#MAX_REQUESTS`                                                | ✗                                 |                     |
      | `ClickHouseDefaults#ROUNDING_MODE`                                               |                                   |                     |
      | `ClickHouseDefaults#SERVER_VERSION`<br />`ClickHouseClientOption#SERVER_VERSION` | `Client.Builder#setServerVersion` |                     |
      | `ClickHouseDefaults#SRV_RESOLVE`                                                 | ✗                                 |                     |
      | `ClickHouseClientOption#CUSTOM_SETTINGS`                                         |                                   |                     |
      | `ClickHouseClientOption#PRODUCT_NAME`                                            | ✗                                 | 클라이언트 이름 사용         |
      | `ClickHouseClientOption#RENAME_RESPONSE_COLUMN`                                  | ✗                                 |                     |
      | `ClickHouseClientOption#SERVER_REVISION`                                         | ✗                                 |                     |
      | `ClickHouseClientOption#TRANSACTION_TIMEOUT`                                     | ✗                                 |                     |
      | `ClickHouseClientOption#WIDEN_UNSIGNED_TYPES`                                    | ✗                                 |                     |
      | `ClickHouseClientOption#USE_BINARY_STRING`                                       | ✗                                 |                     |
      | `ClickHouseClientOption#USE_BLOCKING_QUEUE`                                      | ✗                                 |                     |
      | `ClickHouseClientOption#USE_COMPILATION`                                         | ✗                                 |                     |
      | `ClickHouseClientOption#USE_OBJECTS_IN_ARRAYS`                                   | ✗                                 |                     |
      | `ClickHouseClientOption#MAX_MAPPER_CACHE`                                        | ✗                                 |                     |
      | `ClickHouseClientOption#MEASURE_REQUEST_TIME`                                    | ✗                                 |                     |
    </Tab>
  </Tabs>

  ### 일반적인 차이점

  * Client V2는 이식성을 높이기 위해 전용 클래스 사용을 줄였습니다. 예를 들어 V2는 서버에 데이터를 쓰는 데 `java.io.InputStream`의 모든 구현을 사용할 수 있습니다.
  * Client V2에서 `async` 설정의 기본값은 `off`입니다. 즉, 추가 스레드가 생성되지 않으며 클라이언트 제어를 애플리케이션에서 더 많이 할 수 있습니다. 이 설정은 대부분의 사용 사례에서 `off`로 유지해야 합니다. `async`를 활성화하면 요청마다 별도의 스레드가 생성됩니다. 이는 애플리케이션에서 제어하는
    실행기를 사용할 때만 의미가 있습니다(참조: `com.clickhouse.client.api.Client.Builder#setSharedOperationExecutor`)

  ### 데이터 쓰기

  * `java.io.InputStream`의 어떤 구현이든 사용할 수 있습니다. V1 `com.clickhouse.data.ClickHouseInputStream`도 지원하지만 권장하지는 않습니다.
  * 입력 스트림의 끝이 감지되면 그에 맞게 처리됩니다. 그에 앞서 요청의 출력 스트림을 닫아야 합니다.

  **V1 TSV 포맷 데이터 삽입.**

  ```java theme={null}
  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)) {
      // 입력 데이터를 ClickHouse로 전송하는 워커 스레드를 시작합니다
      future = request.data(requestBody.getInputStream()).execute();

      // inData 스트림에서 requestBody 스트림으로 데이터를 복사합니다

      // 응답을 받기 전에 스트림을 닫아야 합니다
      requestBody.close();

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

  **V2 TSV 포맷 데이터 삽입.**

  ```java theme={null}
  InputStream inData = getInData();
  InsertSettings settings = new InsertSettings().setInputStreamCopyBufferSize(8198 * 2); // 복사 버퍼 크기 설정
  try (InsertResponse response = client.insert(tableName, inData, ClickHouseFormat.TSV, settings).get(30, TimeUnit.SECONDS)) {

    // 이 시점에서 삽입 완료

  } catch (Exception e) {
   // 예외 처리
  }
  ```

  * 호출할 메서드는 하나뿐입니다. 추가 요청 객체를 생성하지 않아도 됩니다.
  * 모든 데이터가 복사되면 요청 본문 스트림이 자동으로 닫힙니다.
  * 새로운 저수준 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`는 데이터에 접근할 수 있게 해 주며, 일부 변환 기능도 제공합니다.

  ```java theme={null}
  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");
  }
  ```
</View>

<View title="v0.7.x">
  DB 서버의 프로토콜을 통해 통신하기 위한 Java 클라이언트 라이브러리입니다. 현재 구현은 [HTTP 인터페이스](/ko/concepts/features/interfaces/http)만 지원합니다. 이 라이브러리는 서버에 요청을 보내기 위한 자체 API를 제공합니다.

  <Warning>
    **지원 중단 예정**

    이 라이브러리는 곧 지원 중단될 예정입니다. 새 프로젝트에서는 최신 [Java 클라이언트](/ko/integrations/language-clients/java/client)를 사용하세요
  </Warning>

  ## Setup

  <Tabs>
    <Tab title="Maven">
      ```xml theme={null}
      <!-- 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>
      ```
    </Tab>

    <Tab title="Gradle (Kotlin)">
      ```kotlin theme={null}
      // https://mvnrepository.com/artifact/com.clickhouse/clickhouse-http-client
      implementation("com.clickhouse:clickhouse-http-client:0.7.2")
      ```
    </Tab>

    <Tab title="Gradle">
      ```groovy theme={null}
      // https://mvnrepository.com/artifact/com.clickhouse/clickhouse-http-client
      implementation 'com.clickhouse:clickhouse-http-client:0.7.2'
      ```
    </Tab>
  </Tabs>

  `0.5.0` 버전부터 driver는 새 클라이언트 HTTP 라이브러리를 사용하므로, 이를 의존성에 추가해야 합니다.

  <Tabs>
    <Tab title="Maven">
      ```xml theme={null}
      <!-- 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>
      ```
    </Tab>

    <Tab title="Gradle (Kotlin)">
      ```kotlin theme={null}
      // https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5
      implementation("org.apache.httpcomponents.client5:httpclient5:5.3.1")
      ```
    </Tab>

    <Tab title="Gradle">
      ```groovy theme={null}
      // https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5
      implementation 'org.apache.httpcomponents.client5:httpclient5:5.3.1'
      ```
    </Tab>
  </Tabs>

  ## 초기화

  연결 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`

  단일 노드에 연결:

  ```java showLineNumbers theme={null}
  ClickHouseNode server = ClickHouseNode.of("http://localhost:8123/default?compress=0");
  ```

  여러 노드로 구성된 클러스터에 연결하십시오:

  ```java showLineNumbers theme={null}
  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

  ```java showLineNumbers theme={null}
  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

  ```java showLineNumbers theme={null}
  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();
          }
  }
  ```

  [저장소](https://github.com/ClickHouse/clickhouse-java/tree/main/examples/client)에서 [전체 코드 예시](https://github.com/ClickHouse/clickhouse-java/blob/main/examples/client/src/main/java/com/clickhouse/examples/jdbc/Main.java#L73)를 확인하세요.

  ## 삽입 API

  ```java showLineNumbers theme={null}
  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();
  }
  ```

  [저장소](https://github.com/ClickHouse/clickhouse-java/tree/main/examples/client)에서 [전체 코드 예시](https://github.com/ClickHouse/clickhouse-java/blob/main/examples/client/src/main/java/com/clickhouse/examples/jdbc/Main.java#L39)를 확인하십시오.

  **RowBinary 인코딩**

  RowBinary 포맷에 대한 자세한 내용은 해당 [페이지](/ko/reference/formats/RowBinary/RowBinaryWithNamesAndTypes)를 참조하십시오.

  [코드 예시](https://github.com/ClickHouse/clickhouse-kafka-connect/blob/main/src/main/java/com/clickhouse/kafka/connect/sink/db/ClickHouseWriter.java#L622)가 있습니다.

  ## 기능

  ### 압축(Compression)

  클라이언트는 기본적으로 LZ4 압축(Compression)을 사용하며, 이를 위해 다음 의존성이 필요합니다:

  <Tabs>
    <Tab title="Maven">
      ```xml theme={null}
      <!-- https://mvnrepository.com/artifact/org.lz4/lz4-java -->
      <dependency>
          <groupId>org.lz4</groupId>
          <artifactId>lz4-java</artifactId>
          <version>1.8.0</version>
      </dependency>
      ```
    </Tab>

    <Tab title="Gradle (Kotlin)">
      ```kotlin theme={null}
      // https://mvnrepository.com/artifact/org.lz4/lz4-java
      implementation("org.lz4:lz4-java:1.8.0")
      ```
    </Tab>

    <Tab title="Gradle">
      ```groovy theme={null}
      // https://mvnrepository.com/artifact/org.lz4/lz4-java
      implementation 'org.lz4:lz4-java:1.8.0'
      ```
    </Tab>
  </Tabs>

  연결 URL에 `compress_algorithm=gzip`을 설정하여 gzip을 대신 사용할 수도 있습니다.

  또는 다음과 같은 몇 가지 방법으로 압축을 비활성화할 수 있습니다.

  1. connection URL에 `compress=0`을 설정해 비활성화합니다: `http://localhost:8123/default?compress=0`
  2. 클라이언트 구성에서 비활성화하십시오:

  ```java showLineNumbers theme={null}
  ClickHouseClient client = ClickHouseClient.builder()
     .config(new ClickHouseConfig(Map.of(ClickHouseClientOption.COMPRESS, false)))
     .nodeSelector(ClickHouseNodeSelector.of(ClickHouseProtocol.HTTP))
     .build();
  ```

  다양한 압축 옵션에 대한 자세한 내용은 [압축 문서](/ko/guides/clickhouse/data-modelling/compression/compression-modes)를 참조하십시오.

  ### 다중 쿼리

  동일한 세션 내에서 워커 스레드로 여러 쿼리를 순차적으로 실행합니다:

  ```java showLineNumbers theme={null}
  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` 함수를 사용해 이용할 수 있습니다.

  ```java showLineNumbers theme={null}
  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()) {
              //...
          }
  }
  ```

  <Info>
    **매개변수**

    `String` 타입(`String`, `String[]`, `Map<String, String>`)이 포함된 모든 `params` 시그니처에서는 전달되는 키가 유효한 ClickHouse SQL 문자열이라고 가정합니다. 예를 들면 다음과 같습니다:

    ```java showLineNumbers theme={null}
    try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
         ClickHouseResponse response = client.read(servers)
            .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
            .query("select * from my_table where name=:name")
            .params(Map.of("name","'Ben'"))
            .executeAndWait()) {
                //...
            }
    }
    ```

    String 객체를 수동으로 파싱해 ClickHouse SQL로 변환하고 싶지 않다면, `com.clickhouse.data`에 있는 도우미 함수 `ClickHouseValues.convertToSqlExpression`를 사용할 수 있습니다:

    ```java showLineNumbers theme={null}
    try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
         ClickHouseResponse response = client.read(servers)
            .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
            .query("select * from my_table where name=:name")
            .params(Map.of("name", ClickHouseValues.convertToSqlExpression("Ben's")))
            .executeAndWait()) {
                //...
            }
    }
    ```

    위의 예시에서 `ClickHouseValues.convertToSqlExpression`는 내부 작은따옴표를 이스케이프하고, 변수를 올바른 작은따옴표로 둘러쌉니다.

    `Integer`, `UUID`, `Array`, `Enum`과 같은 다른 타입은 `params` 내에서 자동으로 변환됩니다.
  </Info>

  ## 노드 디스커버리

  Java 클라이언트는 ClickHouse 노드를 자동으로 검색하는 디스커버리 기능을 제공합니다. 자동 디스커버리는 기본적으로 비활성화되어 있습니다. 활성화하려면 `auto_discovery`를 `true`로 설정하십시오:

  ```java theme={null}
  properties.setProperty("auto_discovery", "true");
  ```

  또는 연결 URL에서:

  ```plaintext theme={null}
  jdbc:ch://my-server/system?auto_discovery=true
  ```

  자동 디스커버리가 활성화된 경우, 연결 URL에 모든 ClickHouse 노드를 지정하지 않아도 됩니다. URL에 지정된 노드는 시드(seed)로 처리되며, Java 클라이언트가 시스템 테이블(system tables) 및/또는 clickhouse-keeper나 ZooKeeper를 통해 추가 노드를 자동으로 검색합니다.

  다음 옵션들은 자동 디스커버리 구성을 담당합니다:

  | 속성                        | 기본값     | 설명                                                                                      |
  | ------------------------- | ------- | --------------------------------------------------------------------------------------- |
  | auto\_discovery           | `false` | 클라이언트가 시스템 테이블(system tables) 및/또는 clickhouse-keeper/ZooKeeper에서 추가 노드를 자동으로 찾을지 여부입니다. |
  | node\_discovery\_interval | `0`     | 밀리초 단위의 노드 디스커버리 간격이며, 값이 0 이하이면 1회성 디스커버리를 의미합니다.                                      |
  | node\_discovery\_limit    | `100`   | 한 번에 디스커버리할 수 있는 최대 노드 수입니다. 값이 0 이하이면 제한이 없습니다.                                        |

  ### 로드 밸런싱

  Java 클라이언트는 로드 밸런싱 정책에 따라 요청을 보낼 ClickHouse 노드를 선택합니다. 일반적으로 로드 밸런싱 정책은 다음 사항을 담당합니다.

  1. 관리형 노드 목록에서 노드를 조회합니다.
  2. 노드 상태 관리.
  3. 선택적으로 노드 디스커버리용 백그라운드 프로세스를 예약하고(자동 디스커버리가 활성화된 경우) 상태 점검을 실행합니다.

  로드 밸런싱을 구성하는 옵션 목록은 다음과 같습니다:

  | 속성                      | 기본값                                      | 설명                                                                                                                                                                                                                                                                                                                  |
  | ----------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | load\_balancing\_policy | `""`                                     | 로드 밸런싱 정책은 다음 중 하나로 설정할 수 있습니다: <li>`firstAlive` - 요청이 관리 노드 목록에서 첫 번째 정상 노드로 전송됩니다</li><li>`random` - 요청이 관리 노드 목록에서 임의의 노드로 전송됩니다 </li><li>`roundRobin` - 요청이 관리 노드 목록의 각 노드로 순차적으로 전송됩니다.</li><li>`ClickHouseLoadBalancingPolicy`를 구현하는 정규화된 클래스 이름 - 사용자 지정 로드 밸런싱 정책</li>지정하지 않으면 요청이 관리 노드 목록의 첫 번째 노드로 전송됩니다 |
  | load\_balancing\_tags   | `""`                                     | 노드를 필터링하기 위한 로드 밸런싱 태그입니다. 요청은 지정된 태그가 있는 노드로만 전송됩니다.                                                                                                                                                                                                                                                               |
  | health\_check\_interval | `0`                                      | 밀리초 단위의 상태 확인 간격입니다. 값이 0 이하이면 한 번만 실행됩니다.                                                                                                                                                                                                                                                                          |
  | health\_check\_method   | `ClickHouseHealthCheckMethod.SELECT_ONE` | 헬스 체크 메서드입니다. 다음 중 하나를 사용할 수 있습니다: <li>`ClickHouseHealthCheckMethod.SELECT_ONE` - `select 1` 쿼리로 확인</li> <li>`ClickHouseHealthCheckMethod.PING` - 프로토콜별 확인으로, 일반적으로 더 빠릅니다</li>                                                                                                                                     |
  | node\_check\_interval   | `0`                                      | 밀리초 단위의 노드 검사 간격입니다. 음수는 0으로 처리됩니다. 마지막 검사 이후 지정된 시간이 지나면 노드 상태를 검사합니다.<br />`health_check_interval`과 `node_check_interval`의 차이점은 `health_check_interval` 옵션이 노드 목록(전체 또는 장애가 있는 노드)의 상태를 검사하는 백그라운드 작업을 예약하는 반면, `node_check_interval`은 특정 노드의 마지막 검사 이후 얼마나 시간이 지나야 하는지를 지정한다는 점입니다.                              |
  | check\_all\_nodes       | `false`                                  | 모든 노드에 대해 헬스 체크를 수행할지, 아니면 장애가 있는 노드에 대해서만 수행할지를 지정합니다.                                                                                                                                                                                                                                                             |

  ### 장애 조치 및 재시도

  Java 클라이언트는 실패한 쿼리에 대한 failover 및 retry 동작을 구성할 수 있는 옵션을 제공합니다:

  | 속성                        | 기본값    | 설명                                                                                                                                              |
  | ------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
  | 장애 조치                     | `0`    | 요청에서 장애 조치가 발생할 수 있는 최대 횟수입니다. 0 또는 음수 값은 장애 조치를 수행하지 않음을 의미합니다. 장애 조치는 실패한 요청을 다른 노드로 전송하여(로드 밸런싱 정책에 따름) 장애를 복구합니다.                           |
  | 재시도                       | `0`    | 요청에 대해 재시도할 수 있는 최대 횟수입니다. 0 또는 음수 값은 재시도하지 않음을 의미합니다. 재시도는 요청을 동일한 노드로 다시 보내며, ClickHouse 서버가 `NETWORK_ERROR` 오류 코드를 반환한 경우에만 수행됩니다.           |
  | repeat\_on\_session\_lock | `true` | 세션이 잠긴 경우 시간 초과(`session_timeout` 또는 `connect_timeout` 기준)될 때까지 실행을 반복할지 여부입니다. ClickHouse 서버가 `SESSION_IS_LOCKED` 오류 코드를 반환하면 실패한 요청을 다시 시도합니다 |

  ### 사용자 지정 HTTP 헤더 추가하기

  요청에 사용자 지정 HTTP 헤더를 추가해야 하는 경우 Java 클라이언트는 HTTP/S 전송 계층을 지원합니다.
  `custom&#95;http&#95;headers` 속성을 사용해야 하며, 헤더는 `,`로 구분되어야 합니다. 헤더의 키/값은 `=`로 구분합니다.

  ## Java 클라이언트 지원

  ```java theme={null}
  options.put("custom_http_headers", "X-ClickHouse-Quota=test, X-ClickHouse-Test=test");
  ```

  ## JDBC 드라이버

  ```java theme={null}
  properties.setProperty("custom_http_headers", "X-ClickHouse-Quota=test, X-ClickHouse-Test=test");
  ```
</View>
