Skip to content

Commit e353f0c

Browse files
committed
enhance http client and jdbc driver
1 parent 5db1b84 commit e353f0c

File tree

67 files changed

+2905
-1632
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+2905
-1632
lines changed

README.md

Lines changed: 62 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,96 @@
11
# ClickHouse Java Client & JDBC Driver
22

3-
[![clickhouse-jdbc](https://maven-badges.herokuapp.com/maven-central/ru.yandex.clickhouse/clickhouse-jdbc/badge.svg)](https://maven-badges.herokuapp.com/maven-central/ru.yandex.clickhouse/clickhouse-jdbc) ![Build Status(https://github.com/ClickHouse/clickhouse-jdbc/workflows/Build/badge.svg)](https://github.com/ClickHouse/clickhouse-jdbc/workflows/Build/badge.svg) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=ClickHouse_clickhouse-jdbc&metric=coverage)](https://sonarcloud.io/dashboard?id=ClickHouse_clickhouse-jdbc)
3+
[![clickhouse-jdbc](https://maven-badges.herokuapp.com/maven-central/com.clickhouse/clickhouse-jdbc/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.clickhouse/clickhouse-jdbc) ![Build Status(https://github.com/ClickHouse/clickhouse-jdbc/workflows/Build/badge.svg)](https://github.com/ClickHouse/clickhouse-jdbc/workflows/Build/badge.svg) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=ClickHouse_clickhouse-jdbc&metric=coverage)](https://sonarcloud.io/dashboard?id=ClickHouse_clickhouse-jdbc)
44

5-
Java client and JDBC driver for ClickHouse.
5+
Java client and JDBC driver for ClickHouse. Java client is async and light weight library for accessing ClickHouse in Java; while JDBC driver is built on top of the Java client with more dependencies and extensions for JDBC-compliance.
66

77
## Usage
88

99
### Java Client
1010

11-
Use Java client when you prefer async and more "direct" way to communicate with ClickHouse. JDBC driver is actually a thin wrapper of the Java client.
12-
1311
```xml
1412
<dependency>
1513
<groupId>com.clickhouse</groupId>
16-
<!-- you'll be able to use clickhouse-http-client and clickhouse-tcp-client as well in the near future -->
17-
<artifactId>clickhouse-grpc-client</artifactId>
14+
<!-- or clickhouse-grpc-client if you prefer gRPC -->
15+
<artifactId>clickhouse-http-client</artifactId>
1816
<version>0.3.2</version>
1917
</dependency>
2018
```
2119

22-
Example:
23-
24-
```Java
25-
// declare a server to connect to
26-
ClickHouseNode server = ClickHouseNode.of("server.domain", ClickHouseProtocol.GRPC, 9100, "my_db");
27-
28-
// run multiple queries in one go and wait until it's finished
29-
ClickHouseClient.send(server,
30-
"create database if not exists test",
31-
"use test", // change current database from my_db to test
32-
"create table if not exists test_table(s String) engine=Memory",
33-
"insert into test_table values('1')('2')('3')",
34-
"select * from test_table limit 1",
35-
"truncate table test_table",
36-
"drop table if exists test_table").get();
37-
38-
// query with named parameters
39-
try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.GRPC);
40-
ClickHouseResponse resp = client.connect(server)
41-
.format(ClickHouseFormat.RowBinaryWithNamesAndTypes).set("send_logs_level", "trace")
42-
.query("select id, name from some_table where id in :ids and name like :name").params(Arrays.asList(1,2,3), "%key%").execute().get()) {
43-
// you can also use resp.stream() as well
44-
for (ClickHouseRecord record : resp.records()) {
45-
int id = record.getValue(0).asInteger();
46-
String name = record.getValue(1).asString();
20+
<details>
21+
<summary>Expand to see example...</summary>
22+
23+
```Java
24+
// declare a server to connect to
25+
ClickHouseNode server = ClickHouseNode.of("server.domain", ClickHouseProtocol.HTTP, 8123, "my_db");
26+
27+
// run multiple queries in one go and wait until they're completed
28+
ClickHouseClient.send(server, "create database if not exists test",
29+
"use test", // change current database from my_db to test
30+
"create table if not exists test_table(s String) engine=Memory",
31+
"insert into test_table values('1')('2')('3')",
32+
"select * from test_table limit 1",
33+
"truncate table test_table",
34+
"drop table if exists test_table").get();
35+
36+
// query with named parameters
37+
try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.GRPC);
38+
ClickHouseResponse resp = client.connect(server)
39+
.format(ClickHouseFormat.RowBinaryWithNamesAndTypes).set("send_logs_level", "trace")
40+
.query("select id, name from some_table where id in :ids and name like :name").params(Arrays.asList(1,2,3), "%key%").execute().get()) {
41+
// you can also use resp.stream() as well
42+
for (ClickHouseRecord record : resp.records()) {
43+
int id = record.getValue(0).asInteger();
44+
String name = record.getValue(1).asString();
45+
}
46+
47+
ClickHouseResponseSummary summary = resp.getSummary();
48+
long totalRows = summary.getRows();
4749
}
4850

49-
ClickHouseResponseSummary summary = resp.getSummary();
50-
long totalRows = summary.getRows();
51-
}
51+
// load data with custom writer
52+
ClickHouseClient.load(server, "target_table", ClickHouseFormat.TabSeparated,
53+
ClickHouseCompression.NONE, new ClickHouseWriter() {
54+
@Override
55+
public void write(OutputStream output) throws IOException {
56+
output.write("1\t\\N\n".getBytes());
57+
output.write("2\t123".getBytes());
58+
}
59+
}).get();
60+
```
61+
</details>
5262

53-
// load data with custom writer
54-
ClickHouseClient.load(server, "target_table", ClickHouseFormat.TabSeparated,
55-
ClickHouseCompression.NONE, new ClickHouseWriter() {
56-
@Override
57-
public void write(OutputStream output) throws IOException {
58-
output.write("1\t\\N\n".getBytes());
59-
output.write("2\t123".getBytes());
60-
}
61-
}).get();
62-
```
6363

6464
### JDBC Driver
6565

6666
```xml
6767
<dependency>
68-
<!-- groupId and package name will be changed to com.clickhouse starting from 0.4.0 -->
69-
<groupId>ru.yandex.clickhouse</groupId>
68+
<!-- ru.yandex.clickhouse will be retired starting from 0.4.0 -->
69+
<groupId>com.clickhouse</groupId>
7070
<artifactId>clickhouse-jdbc</artifactId>
7171
<version>0.3.2</version>
72+
<!-- below is only needed when all you want is a shaded jar -->
73+
<classifier>http</classifier>
74+
<exclusions>
75+
<exclusion>
76+
<groupId>*</groupId>
77+
<artifactId>*</artifactId>
78+
</exclusion>
79+
</exclusions>
7280
</dependency>
7381
```
7482

75-
URL syntax: `jdbc:clickhouse://<host>:<port>[/<database>[?param1=value1&param2=value2]]`, e.g. `jdbc:clickhouse://localhost:8123/test?socket_timeout=120000`
83+
URL Syntax: `jdbc:(clickhouse|ch)[:(grpc|http)]://<host>:[<port>][/<database>[?param1=value1&param2=value2]]`
84+
- `jdbc:ch:grpc://localhost` is same as `jdbc:clickhouse:grpc://localhost:9100`
85+
- `jdbc:ch://localhost/test?socket_timeout=120000` is same as `jdbc:clickhouse:http://localhost:8123/test?socket_timeout=120000`
7686

77-
JDBC Driver Class: `ru.yandex.clickhouse.ClickHouseDriver` (will be changed to `com.clickhouse.jdbc.ClickHouseDriver` starting from 0.4.0)
87+
JDBC Driver Class: `com.clickhouse.jdbc.ClickHouseDriver` (will remove `ru.yandex.clickhouse.ClickHouseDriver` starting from 0.4.0)
7888

7989
For example:
8090

8191
```java
82-
String url = "jdbc:clickhouse://localhost:8123/test";
83-
ClickHouseProperties properties = new ClickHouseProperties();
92+
String url = "jdbc:ch://localhost/test";
93+
Properties properties = new Properties();
8494
// set connection options - see more defined in ClickHouseConnectionSettings
8595
properties.setClientName("Agent #1");
8696
...
@@ -96,13 +106,11 @@ additionalDBParams.put(ClickHouseQueryParam.SESSION_ID, "new-session-id");
96106
...
97107
try (ClickHouseConnection conn = dataSource.getConnection();
98108
ClickHouseStatement stmt = conn.createStatement();
99-
ResultSet rs = stmt.executeQuery(sql, additionalDBParams)) {
109+
ResultSet rs = stmt.executeQuery(sql)) {
100110
...
101111
}
102112
```
103113

104-
Additionally, if you have a few instances, you can use `BalancedClickhouseDataSource`.
105-
106114
### Extended API
107115

108116
In order to provide non-JDBC complaint data manipulation functionality, proprietary API exists.
@@ -174,7 +182,7 @@ Java 8 or higher is required in order to use Java client and/or JDBC driver.
174182
| \*String | Y | Y | |
175183
| UUID | Y | Y | |
176184
| AggregatedFunction | N | N | Partially supported |
177-
| Array | Y | N | |
185+
| Array | Y | Y | |
178186
| Map | Y | Y | |
179187
| Nested | Y | N | |
180188
| Tuple | Y | N | |

clickhouse-benchmark/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
<properties>
1919
<clickhouse4j-driver.version>1.4.4</clickhouse4j-driver.version>
20-
<native-driver.version>2.6.0</native-driver.version>
20+
<native-driver.version>2.6.1</native-driver.version>
2121
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
2222
<jmh.version>1.33</jmh.version>
2323
<shade.name>benchmarks</shade.name>
@@ -138,7 +138,7 @@
138138
<filter>
139139
<artifact>*:*</artifact>
140140
<excludes>
141-
<exclude>module-info.class</exclude>
141+
<exclude>**/module-info.class</exclude>
142142
<exclude>META-INF/MANIFEST.MF</exclude>
143143
<exclude>META-INF/*.SF</exclude>
144144
<exclude>META-INF/*.DSA</exclude>

clickhouse-benchmark/src/main/java/com/clickhouse/benchmark/jdbc/DriverState.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.clickhouse.benchmark.BaseState;
1616
import com.clickhouse.benchmark.Constants;
1717
import com.clickhouse.benchmark.ServerState;
18+
// import com.github.housepower.settings.ClickHouseDefines;
1819

1920
@State(Scope.Thread)
2021
public class DriverState extends BaseState {
@@ -49,6 +50,8 @@ public void doSetup(ServerState serverState) throws Exception {
4950
url = String.format(jdbcDriver.getUrlTemplate(), serverState.getHost(),
5051
serverState.getPort(jdbcDriver.getDefaultPort()), serverState.getDatabase(), serverState.getUser(),
5152
serverState.getPassword(), compression);
53+
// ClickHouseDefines.WRITE_COMPRESS = false;
54+
// ClickHouseDefines.READ_DECOMPRESS = Boolean.parseBoolean(compression);
5255
conn = driver.connect(url, new Properties());
5356

5457
try (Statement s = conn.createStatement()) {

clickhouse-benchmark/src/main/java/com/clickhouse/benchmark/jdbc/Query.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
public class Query extends DriverBenchmark {
99
@Benchmark
10-
public void selectArrayOfInts(Blackhole blackhole, DriverState state) throws Throwable {
10+
public void selectArrayOfUInt16(Blackhole blackhole, DriverState state) throws Throwable {
1111
int num = state.getRandomNumber();
1212
int rows = state.getSampleSize() + num;
1313
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getArray(i)));
@@ -21,7 +21,7 @@ public void selectArrayOfInts(Blackhole blackhole, DriverState state) throws Thr
2121
}
2222

2323
@Benchmark
24-
public void selectMapOfInts(Blackhole blackhole, DriverState state) throws Throwable {
24+
public void selectMapOfInt32(Blackhole blackhole, DriverState state) throws Throwable {
2525
int num = state.getRandomNumber();
2626
int rows = state.getSampleSize() + num;
2727
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getObject(i)));
@@ -36,12 +36,12 @@ public void selectMapOfInts(Blackhole blackhole, DriverState state) throws Throw
3636
}
3737

3838
@Benchmark
39-
public void selectTupleOfInts(Blackhole blackhole, DriverState state) throws Throwable {
39+
public void selectTupleOfInt16(Blackhole blackhole, DriverState state) throws Throwable {
4040
int num = state.getRandomNumber();
4141
int rows = state.getSampleSize() + num;
42-
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getArray(i)));
42+
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getObject(i)));
4343
try (Statement stmt = executeQuery(state,
44-
"select tuple(range(100, number % 600)) as v from numbers(?)", rows)) {
44+
"select tuple(arrayMap(x -> cast(x as Int16), range(100, number % 600))) as v from numbers(?)", rows)) {
4545
ResultSet rs = stmt.getResultSet();
4646
while (rs.next()) {
4747
func.consume(blackhole, rs, 1);
@@ -103,6 +103,19 @@ public void selectUInt8(Blackhole blackhole, DriverState state) throws Throwable
103103
}
104104
}
105105

106+
@Benchmark
107+
public void selectUuid(Blackhole blackhole, DriverState state) throws Throwable {
108+
int num = state.getRandomNumber();
109+
int rows = state.getSampleSize() + num;
110+
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getString(i)));
111+
try (Statement stmt = executeQuery(state, "select generateUUIDv4() as v from numbers(?)", rows)) {
112+
ResultSet rs = stmt.getResultSet();
113+
while (rs.next()) {
114+
func.consume(blackhole, rs, 1);
115+
}
116+
}
117+
}
118+
106119
@Benchmark
107120
public void selectInt32(Blackhole blackhole, DriverState state) throws Throwable {
108121
int num = state.getRandomNumber();

clickhouse-client/src/main/java/com/clickhouse/client/ClickHouseClientBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public ClickHouseClient build() {
9797

9898
boolean noSelector = nodeSelector == null || nodeSelector == ClickHouseNodeSelector.EMPTY;
9999
int counter = 0;
100-
for (ClickHouseClient c : ServiceLoader.load(ClickHouseClient.class)) {
100+
for (ClickHouseClient c : ServiceLoader.load(ClickHouseClient.class, getClass().getClassLoader())) {
101101
counter++;
102102
if (noSelector || nodeSelector.match(c)) {
103103
client = c;

0 commit comments

Comments
 (0)