/clickhouse-jdbc

JDBC driver for ClickHouse

Primary LanguageJavaApache License 2.0Apache-2.0

ClickHouse Java Client & JDBC Driver

GitHub release (latest SemVer including pre-releases) Build Status(https://github.com/ClickHouse/clickhouse-jdbc/workflows/Build/badge.svg) Coverage

Java client and JDBC driver for ClickHouse. Java client is async, lightweight, and low-overhead library for ClickHouse; while JDBC driver is built on top of the Java client with more dependencies and extensions for JDBC-compliance.

Java 8 or higher is required in order to use Java client(clickhouse-client) and/or JDBC driver(clickhouse-jdbc). In addition, starting from 0.3.2, JDBC driver only works with ClickHouse 20.7 or above, so please consider to either downgrade the driver to 0.3.1-patch or upgrade server to one of active releases.


IMPORTANT

Maven groupId ru.yandex.clickhouse and legacy JDBC driver ru.yandex.clickhouse.ClickHouseDriver have been deprecated and no longer receive updates.

Please use new groupId com.clickhouse and driver com.clickhouse.jdbc.ClickHouseDriver instead. It's highly recommended to upgrade to 0.3.2+ now for improved performance and stability.

image Note: in general, the new driver(v0.3.2) is a few times faster with less memory usage. More information can be found at here.


Features

Category Feature Supported Remark
API JDBC
R2DBC will be supported in 0.3.3
Protocol HTTP recommended, defaults to java.net.HttpURLConnection and can be changed to java.net.http.HttpClient(faster but less stable)
gRPC still experimental, works with 22.3+, known to has issue when using LZ4 compression
TCP/Native clickhouse-cli-client(wrapper of ClickHouse native command-line client) was added in 0.3.2-patch10, clickhouse-tcp-client will be available in 0.3.3
Compatibility Server < 20.7 use 0.3.1-patch(or 0.2.6 if you're stuck with JDK 7)
Server >= 20.7 use 0.3.2 or above. All active releases are supported.
Data Format RowBinary RowBinaryWithNamesAndTypes for query and RowBinary for insertion
TabSeparated Does not support as many data types as RowBinary
Data Type AggregatedFunction limited to groupBitmap
Array(*)
Bool
Date*
DateTime*
Decimal* SET output_format_decimal_trailing_zeros=1 in 21.9+ for consistency
Enum* can be treated as both string and integer
Geo Types Point, Ring, Polygon, and MultiPolygon
Int*, UInt* UInt64 is mapped to long
IPv*
Map(*)
Nested(*)
Object('JSON') supported since 0.3.2-patch8
SimpleAggregateFunction
*String
Tuple(*)
UUID
High Availability Load Balancing supported since 0.3.2-patch10
Failover supported since 0.3.2-patch10

Examples

Java Client

<dependency>
    <groupId>com.clickhouse</groupId>
    <!-- or clickhouse-grpc-client if you prefer gRPC -->
    <artifactId>clickhouse-http-client</artifactId>
    <version>0.3.2-patch10</version>
</dependency>
// endpoint: protocol://host[:port][/database][?param1=value1&param2=value2...][#tag1,tag2,...]
ClickHouseNode endpoint = ClickHouseNode.of("https://localhost"); // http://localhost:8443?ssl=true&sslmode=NONE
// endpoints: [defaultProtocol://]endpoint1[,endpoint2,endpoint3,...][/defaultDatabase][?defaultParameters][#efaultTags]
ClickHouseNodes endpoints = ClickHouseNodes.of("http://(https://explorer@play.clickhouse.com:443),localhost,(tcp://localhost?!auto_discovery#experimental),(grpc://localhost#experimental)?failover=3#test")

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
    ClickHouseResponse response = client.connect(endpoint) // or client.connect(endpoints)
        // you'll have to parse response manually if using a different format
        .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
        .query("select * from numbers(:limit)")
        .params(1000).executeAndWait()) {
    // or response.stream() if you prefer stream API
    for (ClickHouseRecord r : response.records()) {
        int num = r.getValue(0).asInteger();
        // type conversion
        String str = r.getValue(0).asString();
        LocalDate date = r.getValue(0).asDate();
    }

    ClickHouseResponseSummary summary = response.getSummary();
    long totalRows = summary.getTotalRowsToRead();
}

JDBC Driver

<dependency>
    <!-- please stop using ru.yandex.clickhouse as it's been deprecated -->
    <groupId>com.clickhouse</groupId>
    <artifactId>clickhouse-jdbc</artifactId>
    <version>0.3.2-patch10</version>
    <!-- use uber jar with all dependencies included, change classifier to http for smaller jar -->
    <classifier>all</classifier>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>
// jdbc:(ch|clickhouse):[defaultProtocol://]endpoint1[,endpoint2,endpoint3,...][/defaultDatabase][?defaultParameters][#efaultTags]
String url = "jdbc:ch:https://play.clickhouse.com:443";
Properties properties = new Properties();
properties.setProperty("user", "explorer");
properties.setProperty("password", "");
// optional properties
properties.setProperty("client_name", "Agent #1");
...

ClickHouseDataSource dataSource = new ClickHouseDataSource(url, properties);
try (Connection conn = dataSource.getConnection();
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("show databases")) {
    ...
}

Build with Maven

Use mvn clean verify to compile, test and generate shaded packages if you're using JDK 8. To create a multi-release jar file(see JEP-238), please use JDK 11 or above and follow instructions below:

  • make sure you have ~/.m2/toolchains.xml, for example:

    <?xml version="1.0" encoding="UTF8"?>
    <toolchains>
        <toolchain>
            <type>jdk</type>
            <provides>
                <version>11</version>
            </provides>
            <configuration>
                <jdkHome>/usr/lib/jvm/java-11-openjdk</jdkHome>
            </configuration>
        </toolchain>
        <toolchain>
            <type>jdk</type>
            <provides>
                <version>17</version>
            </provides>
            <configuration>
                <jdkHome>/usr/lib/jvm/java-17-openjdk</jdkHome>
            </configuration>
        </toolchain>
    </toolchains>
  • run mvn -Drelease clean install to build and install the artificat to local repository

    Note: if you need to build modules separately, please start with clickhouse-client, followed by clickhouse-http-client and clickhouse-grpc-client, and then clickhouse-jdbc and clickhouse-benchmark.

Benchmark

To benchmark JDBC drivers:

cd clickhouse-benchmark
mvn -Drelease clean package
# single thread mode
java -DdbHost=localhost -jar target/benchmarks.jar -t 1 \
    -p client=clickhouse-jdbc -p connection=reuse \
    -p statement=prepared Query.selectInt8

It's time consuming to run all benchmarks against all drivers using different parameters for comparison. If you just need some numbers to understand performance, please refer to table below and some more details like CPU and memory usage mentioned at here(still have plenty of room to improve according to ranking at here).

Testing

By default, docker container will be created automatically during integration test. You can pass system property like -DclickhouseVersion=21.8 to specify version of ClickHouse.

In the case you prefer to test against an existing server, please follow instructions below:

  • make sure the server can be accessed using default account(user default and no password), which has both DDL and DML privileges
  • add below two configuration files to the existing server and expose all ports for external access
    • ports.xml - enable all ports
    • and users.xml - accounts used for integration test Note: you may need to change root element from clickhouse to yandex when testing old version of ClickHouse.
  • put test.properties under either ~/.clickhouse or src/test/resources of your project, with content like below:
    clickhouseServer=x.x.x.x
    # below properties are only useful for test containers
    #clickhouseVersion=latest
    #clickhouseTimezone=UTC
    #clickhouseImage=clickhouse/clickhouse-server
    #additionalPackages=