1. 概述
通过在线分析处理(OLAP)技术,企业能够洞察当前运营状况并识别改进趋势。这通常通过对聚合业务数据执行复杂分析来实现。
ClickHouse是一款开源的列式OLAP数据库,因其卓越性能而备受关注。
本教程将探索如何将ClickHouse数据库集成到Spring Boot应用中。我们将逐步完成必要配置、建立连接,并对数据库表执行基础CRUD操作。
2. 项目搭建
在开始与ClickHouse数据库交互前,我们需要添加相关SDK依赖并正确配置应用。
2.1. 依赖配置
首先在项目的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定义数据库表
接下来定义我们要操作的数据库表。
我们将使用Flyway管理数据库迁移。添加flyway-core和flyway-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>
在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;
脚本创建了authors表,使用id作为主键。我们采用MergeTree表引擎,该引擎针对插入和查询性能进行了优化。
2.3. 数据模型
最后创建Author记录类表示表数据:
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实例。
3. 使用Testcontainers搭建本地测试环境
为简化本地开发和测试,我们将使用Testcontainers搭建ClickHouse数据库。
运行Testcontainers需要Docker环境支持。
3.1. 测试依赖
在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-testcontainers和clickhouse模块提供了启动ClickHouse数据库容器所需类。
3.2. 定义Testcontainers Bean
创建@TestConfiguration类定义容器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时指定最新稳定版镜像。
然后定义DynamicPropertyRegistrar Bean配置数据源属性,使应用能连接到数据库容器。
配置好连接信息后,Spring Boot会自动创建JdbcTemplate Bean供后续使用。
3.3. 在开发中使用Testcontainers
虽然Testcontainers主要用于集成测试,但也可用于本地开发。
在src/test/java目录创建独立启动类:
class TestApplication {
public static void main(String[] args) {
SpringApplication.from(Application::main)
.with(TestcontainersConfiguration.class)
.run(args);
}
}
创建TestApplication类,在main()方法中启动主应用类并加载TestcontainersConfiguration。
这种配置能帮我们在本地轻松管理外部服务。运行Spring Boot应用时,它会自动连接到Testcontainers启动的数据库服务。
4. 执行CRUD操作
本地环境就绪后,使用JdbcTemplate** Bean操作authors表**:
Author author = Author.create("John Doe", "john@example.com");
jdbcTemplate.update(
"""
INSERT INTO authors (id, name, email, created_at)
VALUES (?, ?, ?, ?);
""",
author.id(),
author.name(),
author.email(),
author.createdAt()
);
使用create()方法创建Author实例,通过JdbcTemplate的*update()*方法插入表中。
为验证数据持久化成功,执行查询:
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();
});
使用*query()*方法通过ID查询记录,并断言结果与保存数据一致。
⚠️ 为简化演示,我们只实现了保存和读取操作。实际开发中可参考ClickHouse SQL参考文档学习更多语法和操作符。
5. 总结
本文介绍了如何将ClickHouse集成到Spring Boot应用中:
✅ 使用Flyway迁移脚本创建数据库表
✅ 通过Testcontainers启动本地测试环境
✅ 使用JdbcTemplate执行基础CRUD操作
这套方案简单粗暴,特别适合快速验证ClickHouse的集成方案。踩坑点在于Testcontainers配置,务必确保Docker环境正常运行。