51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

ClickHouse 数据库简介

1、简介 {#1简介}

通过使用联机分析处理(Online Analytical Processing,OLAP),企业可以深入了解当前的运营情况,并确定改进趋势。这通常是通过对汇总的业务数据进行复杂的分析来实现的。

ClickHouse 是一个开源的、列式 OLAP 数据库,因其出色的 性能 而大受欢迎。

本文将带你了解如何在 Spring Boot 中整合、使用 ClickHouse。

2、项目设置 {#2项目设置}

在开始与 ClickHouse 数据库交互之前,我们需要添加一些 SDK 依赖,并正确配置我们的应用。

2.1、依赖 {#21依赖}

首先,在项目的 pom.xml 中添加必要的依赖:

<dependency>
    <groupId>com.clickhouse</groupId>
    <artifactId>clickhouse-jdbc</artifactId>
    <version>0.7.1</version>
</dependency>
<dependency>
    <groupId>org.lz4</groupId>
    <artifactId>lz4-java</artifactId>
    <version>1.8.0</version>
</dependency>

clickhouse-jdbc 依赖提供了 JDBC API 的实现,使我们能够与 ClickHouse 数据库建立连接并进行交互。

默认情况下,ClickHouse 使用 LZ4 压缩来存储数据,为此我们添加了 lz4-java 依赖项。

2.2、使用 Flyway 定义数据表 {#22使用-flyway-定义数据表}

接下来,定义数据库表,并对其执行操作。

使用 Flyway 来管理数据库迁移。这需要添加 flyway-coreflyway-database-clickhouse 依赖:

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
</dependency>
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-database-clickhouse</artifactId>
    <version>10.16.3</version>
</dependency>

将这些依赖添加到 pom.xml 之后,在 src/main/resources/db/migration 目录中创建一个名为 V001__create_table.sql 的迁移脚本,内容如下:

CREATE TABLE authors (
    id UUID,
    name String,
    email String,
    created_at DateTime
)
ENGINE = MergeTree()
PRIMARY KEY id;

上面的脚本创建了一个以 id 为主键的 authors 表,并创建了其他几列。我们使用 MergeTree引擎,该引擎对插入和查询性能进行了优化。

2.3、Data Model {#23data-model}

最后,创建一个 Author record,表示 authors 表中的数据:

public record Author(
    UUID id,
    String name,
    String email,
    LocalDateTime createdAt) {

    public static Author create(String name, String email) {
        return new Author(
            UUID.randomUUID(),
            name,
            email,
            LocalDateTime.now()
        );
    }
}

我们还添加了一个静态 create() 方法,使用随机 UUID 和当前时间戳实例化 Author record

3、使用 Testcontainers 设置本地测试环境 {#3使用-testcontainers-设置本地测试环境}

为了便于本地开发和测试,我们使用 Testcontainers 来建立 ClickHouse 数据库。

通过 Testcontainers 运行数据库的前提条件是有一个活动的 Docker 实例。

3.1、测试所需的依赖 {#31测试所需的依赖}

首先,在 pom.xml 中添加必要的测试依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-testcontainers</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>clickhouse</artifactId>
    <scope>test</scope>
</dependency>

spring-boot-testcontainersclickhouse-testcontainers 模块的依赖提供了所需的类,用于为我们的 ClickHouse 数据库启动一个临时的 Docker 实例。

3.2、定义 Testcontainers Bean {#32定义-testcontainers-bean}

接下来,创建一个 @TestConfiguration 类来定义 Testcontainers Bean:

@TestConfiguration(proxyBeanMethods = false)
class TestcontainersConfiguration {

    @Bean
    public ClickHouseContainer clickhouseContainer() {
        return new ClickHouseContainer("clickhouse/clickhouse-server:24.11");
    }

    @Bean
    public DynamicPropertyRegistrar dynamicPropertyRegistrar(ClickHouseContainer clickhouseContainer) {
        return registry -> {
            registry.add("spring.datasource.url", clickhouseContainer::getJdbcUrl);
            registry.add("spring.datasource.username", clickhouseContainer::getUsername);
            registry.add("spring.datasource.password", clickhouseContainer::getPassword);
            registry.add("spring.datasource.driver-class-name", clickhouseContainer::getDriverClassName);
        };
    }

}

在创建 ClickHouseContainer Bean 时,我们指定了 ClickHouse 镜像的最新稳定版本。

然后,我们定义一个 DynamicPropertyRegistrar Bean 来配置必要的数据源属性。这样,我们的应用就可以连接到 ClickHouse 数据库容器。

在配置了正确的连接详细信息后,Spring Boot 会自动创建一个 JdbcTemplate Bean(稍后会用到)。

3.3、在开发过程中使用 Testcontainers {#33在开发过程中使用-testcontainers}

虽然 Testcontainers 主要用于集成测试,但我们也可以在本地开发过程中使用它。

为此,需要在 src/test/java 目录中创建一个单独的 main 类:

class TestApplication {

    public static void main(String[] args) {
        SpringApplication.from(Application::main)
          .with(TestcontainersConfiguration.class)
          .run(args);
    }
}

如上,我们创建了一个 TestApplication 类,并在其 main() 方法中使用 TestcontainersConfiguration 类启动我们的 Application 类。

这种设置可帮助我们在本地设置和管理外部服务。我们可以运行 Spring Boot 应用,让它连接到通过 Testcontainers 启动的外部服务。

4、执行 CRUD 操作 {#4执行-crud-操作}

本地环境就绪后,让我们使用 JdbcTemplate Bean 与 authors 表进行交互:

Author author = Author.create("John Doe", "doe.john@baeldung.com");

jdbcTemplate.update(
    """
        INSERT INTO authors (id, name, email, created_at)
        VALUES (?, ?, ?, ?);
    """,
    author.id(),
    author.name(),
    author.email(),
    author.createdAt()
);

如上,我们使用 create() 方法创建一个新的 Author 实例,然后使用 JdbcTemplateupdate() 方法将其插入 authors 表。

为了验证 author record 是否已成功保存,再用它的 id 执行一次读取查询:

List<Author> retrievedAuthors = jdbcTemplate.query(
    "SELECT * FROM authors WHERE id = ?",
    (ResultSet resultSet, int rowNum) -> new Author(
        UUID.fromString(resultSet.getString("id")),
        resultSet.getString("name"),
        resultSet.getString("email"),
        resultSet.getObject("created_at", LocalDateTime.class)
    ),
    author.id()
);

assertThat(retrievedAuthors)
  .hasSize(1)
  .first()
  .satisfies(retrievedAuthor -> {
      assertThat(retrievedAuthor.id()).isEqualTo(author.id());
      assertThat(retrievedAuthor.name()).isEqualTo(author.name());
      assertThat(retrievedAuthor.email()).isEqualTo(author.email());
      assertThat(retrievedAuthor.createdAt()).isNotNull();
  });

我们使用 JdbcTemplatequery() 方法按 id 检索已保存的 author record,并断言检索到的 Author 与我们之前保存的 Author 一致。

出于演示目的,这里只演示了保存和读取操作。你可以参考 ClickHouse 提供的 SQL 参考文档 来进一步了解其语法和操作符。

5、总结 {#5总结}

本文介绍了如何在 Spring Boot 中整合、使用 ClickHouse,以及如何通过 Testcontainers 启动临时的 Clickhouse Docker 实例来进行测试。


Ref:https://www.baeldung.com/spring-boot-olap-clickhouse-database

赞(0)
未经允许不得转载:工具盒子 » ClickHouse 数据库简介