首页 > 编程语言 >Java ClickHouse整合—官方教程

Java ClickHouse整合—官方教程

时间:2023-04-07 21:32:19浏览次数:36  
标签:ps 教程 Java ... into stmt ClickHouse table clickhouse


一、开发环境

  • OpenJDK版本 >= 17
  • ClickHouse:20.7+

 1、支持的数据类型

Format

Support

Comment

AggregatedFunction


limited to groupBitmap, and known to have issue with 64bit bitmap

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')


SimpleAggregateFunction


*String


Tuple(*)


UUID


二、Java客户端方式

1、引入依赖

<dependency>
    <groupId>com.clickhouse</groupId>
    <!-- or clickhouse-grpc-client if you prefer gRPC -->
    <artifactId>clickhouse-http-client</artifactId>
    <version>0.4.0</version>
</dependency>

Java ClickHouse整合—官方教程_sql

2、连接ClickHouse

连接字符串protocol://host[:port][/database][?param[=value][&param[=value]][#tag[,tag]]

示例:

  • http://localhost:8443?ssl=true&sslmode=NONE
  • http://(https://[email protected]:443
  • tcp://localhost?!auto_discovery#experimental),(grpc://localhost#experimental)?failover=3#test
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");

Java ClickHouse整合—官方教程_java_02

3、查询

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()) {
            ClickHouseResponseSummary summary = response.getSummary();
            long totalRows = summary.getTotalRowsToRead();

Java ClickHouse整合—官方教程_sql_03

4、流式查询

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()) {
    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();
    }

Java ClickHouse整合—官方教程_sql_04

5、Insert

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP)) {
    ClickHouseRequest<?> request = client.connect(servers).format(ClickHouseFormat.RowBinaryWithNamesAndTypes);
    // load data into a table and wait until it's completed
    request.write()
        .query("insert into my_table select c2, c3 from input('c1 UInt8, c2 String, c3 Int32')")
        .data(myInputStream).execute().thenAccept(response -> {
            response.close();
        });

Java ClickHouse整合—官方教程_sql_05

6、多语句操作

在同一会话中一个接一个地在工作线程中执行多个语句:

CompletableFuture<List<ClickHouseResponseSummary>> future = ClickHouseClient.send(servers.get(),
    "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");

// block current thread until queries completed, and then retrieve summaries
List<ClickHouseResponseSummary> results = future.get();

Java ClickHouse整合—官方教程_sql_06

三、JDBC Driver方式

clickhouse jdbc实现了标准jdbc接口。它构建在clickhouse客户端之上,提供了自定义类型映射、事务支持、标准同步UPDATE和DELETE语句等附加功能,因此可以轻松地与遗留应用程序和工具一起使用。
clickhouse jdbc API是同步的,通常会有更多的开销(例如SQL解析和类型映射/转换等)。当性能至关重要时,或者如果您喜欢更直接的访问clickhouse的方式,请考虑使用clickhouse客户端。

1、引入依赖

<dependency>
    <groupId>com.clickhouse</groupId>
    <artifactId>clickhouse-jdbc</artifactId>
    <version>0.4.0</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>

Java ClickHouse整合—官方教程_java_07

2、配置

驱动程序类com.clickhouse.jdbc.ClickHouseDriver

连接字符串:例如:jdbc:(ch|clickhouse)[:<protocol>]://endpoint1[,endpoint2,...][/<database>][?param1=value1&param2=value2][#tag1,tag2,...]

  • jdbc:ch://localhostjdbc:clickhouse:http://localhost:8123
  • jdbc:ch:https://localhostjdbc:clickhouse:http://localhost:8443?ssl=true&sslmode=STRICT
  • jdbc:ch:grpc://localhostjdbc:clickhouse:grpc://localhost:9100

连接属性

属性

违约

描述

continueBatchOnError

false

发生错误时是否继续批处理 

createDatabaseIfNotExist

false

如果数据库不存在,是否创建数据库

custom_http_headers

逗号分隔的自定义 HTTP 标头,例如:User-Agent=client1,X-Gateway-Id=123

custom_http_params

逗号分隔的自定义 HTTP 标头,例如:User-Agent=client1,X-Gateway-Id=123

nullAsDefault

0

0-将null值按原样处理,并在将null插入不可为null的列时引发异常;1-按原样处理null值,并禁用插入时的null检查;2-将null替换为查询和插入的相应数据类型的默认值

jdbcCompliance

true

是否支持标准同步 UPDATE/DELETE 和fake transaction

typeMappings

自定义ClickHouse数据类型和Java类之间的映射,这将影响getColumnType()和getObject(class<?>)的结果。例如:UInt128=java.lang.String,UInt256=java.lang.String

wrapperObject

false

getObject()是否应为Array/Tuple返回java.sql.Array/java.sql.Struct。

3、连接到ClickHouse

String url = "jdbc:ch://my-server/system"; // use http protocol and port 8123 by default
// String url = "jdbc:ch://my-server:8443/system?ssl=true&sslmode=strict&&sslrootcert=/mine.crt";
Properties properties = new Properties();
// properties.setProperty("ssl", "true");
// properties.setProperty("sslmode", "NONE"); // NONE to trust all servers; STRICT for trusted only
ClickHouseDataSource dataSource = new ClickHouseDataSource(url, new Properties());
try (Connection conn = dataSource.getConnection("default", "password");
    Statement stmt = conn.createStatement()) {
}

Java ClickHouse整合—官方教程_java_08

4、Query

try (Connection conn = dataSource.getConnection(...);
    Statement stmt = conn.createStatement()) {
    ResultSet rs = stmt.executeQuery("select * from numbers(50000)");
    while(rs.next()) {
        // ...
    }
}

Java ClickHouse整合—官方教程_sql_09

5、Insert

使用 input table函数

具有最佳性能的推荐方式

try (PreparedStatement ps = conn.prepareStatement(
    "insert into mytable select col1, col2 from input('col1 String, col2 DateTime64(3), col3 Int32')")) {
    // the column definition will be parsed so the driver knows there are 3 parameters: col1, col2 and col3
    ps.setString(1, "test"); // col1
    ps.setObject(2, LocalDateTime.now()); // col2, setTimestamp is slow and not recommended
    ps.setInt(3, 123); // col3
    ps.addBatch(); // parameters will be write into buffered stream immediately in binary format
    ...
    ps.executeBatch(); // stream everything on-hand into ClickHouse
}

Java ClickHouse整合—官方教程_sql_10

Insert

它更易于使用,但与输入函数相比,性能更慢

try (PreparedStatement ps = conn.prepareStatement("insert into mytable(* except (description))")) {
    // the driver will issue query "select * except (description) from mytable where 0" for type inferring
    // since description column is excluded, we know there are only two parameters: col1 and col2
    ps.setString(1, "test"); // id
    ps.setObject(2, LocalDateTime.now()); // timestamp
    ps.addBatch(); // parameters will be write into buffered stream immediately in binary format
    ...
    ps.executeBatch(); // stream everything on-hand into ClickHouse
}

Java ClickHouse整合—官方教程_java_11

使用占位符新增

不推荐,因为它基于大型 SQL

// Note: "insert into mytable values(?,?,?)" is treated as "insert into mytable"
try (PreparedStatement ps = conn.prepareStatement("insert into mytable values(trim(?),?,?)")) {
    ps.setString(1, "test"); // id
    ps.setObject(2, LocalDateTime.now()); // timestamp
    ps.setString(3, null); // description
    ps.addBatch(); // append parameters to the query
    ...
    ps.executeBatch(); // issue the composed query: insert into mytable values(...)(...)...(...)
}

Java ClickHouse整合—官方教程_java_12

6、高级接口

处理日期时间和时区

请使用java.time.LocalDateTime或java.time.OffsetDateTime代替java.sql.Timestamp,并使用java.time_LocalDate代替java.sql.Date。

try (PreparedStatement ps = conn.prepareStatement("select date_time from mytable where date_time > ?")) {
    ps.setObject(2, LocalDateTime.now());
    ResultSet rs = ps.executeQuery();
    while(rs.next()) {
        LocalDateTime dateTime = (LocalDateTime) rs.getObject(1);
    }
    ...
}

Java ClickHouse整合—官方教程_sql_13

7、处理聚合函数

// batch insert using input function
try (ClickHouseConnection conn = newConnection(props);
        Statement s = conn.createStatement();
        PreparedStatement stmt = conn.prepareStatement(
                "insert into test_batch_input select id, name, value from input('id Int32, name Nullable(String), desc Nullable(String), value AggregateFunction(groupBitmap, UInt32)')")) {
    s.execute("drop table if exists test_batch_input;"
            + "create table test_batch_input(id Int32, name Nullable(String), value AggregateFunction(groupBitmap, UInt32))engine=Memory");
    Object[][] objs = new Object[][] {
            new Object[] { 1, "a", "aaaaa", ClickHouseBitmap.wrap(1, 2, 3, 4, 5) },
            new Object[] { 2, "b", null, ClickHouseBitmap.wrap(6, 7, 8, 9, 10) },
            new Object[] { 3, null, "33333", ClickHouseBitmap.wrap(11, 12, 13) }
    };
    for (Object[] v : objs) {
        stmt.setInt(1, (int) v[0]);
        stmt.setString(2, (String) v[1]);
        stmt.setString(3, (String) v[2]);
        stmt.setObject(4, v[3]);
        stmt.addBatch();
    }
    int[] results = stmt.executeBatch();
    ...
}

// use bitmap as query parameter
try (PreparedStatement stmt = conn.prepareStatement(
    "SELECT bitmapContains(my_bitmap, toUInt32(1)) as v1, bitmapContains(my_bitmap, toUInt32(2)) as v2 from {tt 'ext_table'}")) {
    stmt.setObject(1, ClickHouseExternalTable.builder().name("ext_table")
            .columns("my_bitmap AggregateFunction(groupBitmap,UInt32)").format(ClickHouseFormat.RowBinary)
            .content(new ByteArrayInputStream(ClickHouseBitmap.wrap(1, 3, 5).toBytes()))
            .asTempTable()
            .build());
    ResultSet rs = stmt.executeQuery();
    Assert.assertTrue(rs.next());
    Assert.assertEquals(rs.getInt(1), 1);
    Assert.assertEquals(rs.getInt(2), 0);
    Assert.assertFalse(rs.next());
}

Java ClickHouse整合—官方教程_java_14

大家好,我是Doker品牌的Sinbad,欢迎点赞和评论,您的鼓励是我们持续更新的动力!欢迎加微信进入技术群聊! 


标签:ps,教程,Java,...,into,stmt,ClickHouse,table,clickhouse
From: https://blog.51cto.com/Doker/6176545

相关文章

  • odoo 开发入门教程系列-约束(Constraints)
    约束(Constraints)上一章介绍了向模型中添加一些业务逻辑的能力。我们现在可以将按钮链接到业务代码,但如何防止用户输入错误的数据?例如,在我们的房地产模块中,没有什么可以阻止用户设置负预期价格。odoo提供了两种设置自动验证恒定式的方法:Python约束andSQL约束。SQL参考:与此......
  • Java学习路径
    一、Java学习路径   1.JavaSE  2.数据库   3.前端  4.JavaWeb  5.SSM框架  6.Linux  7.SpringBoot  8.SpringCloud  9.Hadoop......
  • [Javascript] Improve performance of Array.reduce
    Comparetwocodesnippetconstpeople=[{id:1,name:'John',age:45},{id:2,name:"Op",age:32},{id:3,name:"Wade",age:39}]//option1constres=people.reduce((acc,curr)=>{return({......
  • JAVA - 面向对象编程
    面向对象是在之前基本实现的基础上的又一抽象,这里的“高内聚,低耦合”体现的更加明显,有抽丝剥茧、不断总结的感觉了。学习的时候真的会有拨开云雾见月明的感觉,这种感觉真的会上瘾。你慢慢发现所有的东西都在以自己的规律运转,发现验证使用,真的很有《实践论》的味道。我能做些......
  • java -- Math、BigInteger、BigDecimal类和基本类型的包装类、正则表达式
    Mathjava.lang.Math类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。类似这样的工具类,其所有方法均为静态方法,并且不会创建对象,调用起来非常简单。Math.PI//静态常量publicstaticfinaldoublePI=3.14159265358979323846;abs//返回参数的绝对......
  • Java多版本切换 8-11-17
    Java版本切换在A:\DevEnvironment\javaVersion目录下,创建Windows命令脚本Java8.bat @echooff setJAVA_HOME=A:\DevEnvironment\jdk-1.80_152 setPath=%JAVA_HOME%\bin;%Path% echoVersionhasbeenswitchedtoJava8.Java11.bat @echooff setJAVA_HOME=A:\DevE......
  • 【开源免费】ChatGPT-Java版SDK重磅更新至1.0.10版,支持Tokens计算,快来一键接入。
    简介ChatGPTJava版SDK开源地址:https://github.com/Grt1228/chatgpt-java,目前收获将近1000个star。有bug欢迎朋友们指出,互相学习,所有咨询全部免费。最新版:1.0.10<dependency><groupId>com.unfbx</groupId><artifactId>chatgpt-java</artifactId><version......
  • salesforce学习笔记(3-1)- JavaScript Promise(LWC)
    在JS代码中,Promise到底有什么作用?首先,我们知道的是,Javascript是单线程的,什么意思呢?就是说JS在同一时间只能做一个操作,代码的执行是一行一行进行的:  这种执行方式带来的问题就是在我们打开某个画面的时候,画面可能会卡住转圈、加载中状态很久,用户体验感很差。Promise可用于......
  • oracle, mysql, clickhouse创建表的DDL语句参考
    这里展示的oracle,mysql,clickhouse下面如何创建一个表的DDL语句。请注意这里的数据类型,在不同的表,表示形式不一样。   Oracle的DDL语句 --UPCENTER.PUB_PLATE_INFOdefinitionCREATETABLE"UPCENTER"."PUB_PLATE_INFO"("ISVALID"NUMBER(1,0)NO......
  • Jenkins Maven Java项目
     [root@localhost~]#catx2.sh#!/bin/bashrm-rfjavawebappname=$1pid=`ps-ef|grep$appname|grep'java-jar'|awk'{printf$2}'`echo$pidif[-z$pid];thenecho"$appnamenotstarted"else......