Clickhouse和Mybatis-Plus在SpringBoot中的集成配置与使用教程:包括建表脚本、示例代码和测试指南
本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1.建表语句
-- 建表
CREATE TABLE IF NOT EXISTS tb_stat ( id String, region String, group String, yesterday INT, today INT, stat_date DateTime ) ENGINE = SummingMergeTree PARTITION BY ( toYYYYMM ( stat_date ), region ) ORDER BY ( toStartOfHour ( stat_date ), region, group );
-- 数据
INSERT INTO tb_stat VALUES( '1','1232364', '111', 32, 2, '2021-07-09 12:56:00' );
INSERT INTO tb_stat VALUES( '2','1232364', '111', 34, 44, '2021-07-09 12:21:00' );
INSERT INTO tb_stat VALUES( '3','1232364', '111', 54, 12, '2021-07-09 12:20:00' );
INSERT INTO tb_stat VALUES( '4','1232364', '222', 45, 11, '2021-07-09 12:13:00' );
INSERT INTO tb_stat VALUES( '5','1232364', '222', 32, 33, '2021-07-09 12:44:00' );
INSERT INTO tb_stat VALUES( '6','1232364', '222', 12, 23, '2021-07-09 12:22:00' );
INSERT INTO tb_stat VALUES( '7','1232364', '333', 54, 54, '2021-07-09 12:11:00' );
INSERT INTO tb_stat VALUES( '8','1232364', '333', 22, 74, '2021-07-09 12:55:00' );
INSERT INTO tb_stat VALUES( '9','1232364', '333', 12, 15, '2021-07-09 12:34:00' );
2.依赖
这里只粘贴相关依赖:
<!-- https://mvnrepository.com/artifact/ru.yandex.clickhouse/clickhouse-jdbc -->
<dependency>
<groupId>ru.yandex.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>0.2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
3.配置
application.yml 配置:SpringBoot默认是不注入 clickhouse 属性值的,需要自己绑定。
server:
port: 8080
spring:
datasource:
# 数据源选择
type: com.alibaba.druid.pool.DruidDataSource
# clickhouse配置
click:
driverClassName: ru.yandex.clickhouse.ClickHouseDriver
url: jdbc:clickhouse://172.81.205.216:8123/default
username: default
password:
initialSize: 10
maxActive: 100
minIdle: 10
maxWait: 6000
Bean配置:用了druid监控所以在这里边初始化了,这个 DataSource 也可以在启动类里初始化。
@Configuration
public class DruidConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.click")
public DataSource druidDataSource() {
return new DruidDataSource();
}
}
// 或者用
@SpringBootApplication
@MapperScan(value = "com.example.demo.**.mapper")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.click")
public DataSource druidDataSource() {
return new DruidDataSource();
}
}
3.使用
尝试使用mybatis-plus-generator代码生成报错:
DB::Exception: Syntax error: failed at position 6 ('table') (line 1, col 6): table status WHERE 1=1 AND NAME IN ('tb_stat')
所以entity、mapper、service、controller使用的是其他库表生成的代码然后修改的。这里只贴出重要的类: entity代码: statDate字段要使用@JsonFormat格式化日期字符串。
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(value = "tb_stat")
@ApiModel(value = "Stat对象", description = "")
public class Stat implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID")
private String id;
@ApiModelProperty(value = "区域")
private String region;
@ApiModelProperty(value = "分组")
private String group;
@ApiModelProperty(value = "昨天")
private Integer yesterday;
@ApiModelProperty(value = "今天")
private Integer today;
@ApiModelProperty(value = "时间")
@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")
private Date statDate;
}
controller代码:
@RestController
@RequestMapping("/stat")
public class StatController {
@Autowired
private IStatService statService;
@PostMapping("/add")
public boolean addStat(@RequestBody Stat stat) {
return statService.save(stat);
}
@GetMapping("/del/{id}")
public boolean delStatById(@PathVariable String id) {
return statService.removeById(id);
}
@PostMapping("/update")
public boolean updateStat(@RequestBody Stat stat) {
return statService.updateById(stat);
}
@PostMapping("/list")
public List<Stat> getStatList() {
LambdaQueryWrapper<Stat> query = Wrappers.lambdaQuery(Stat.class);
return statService.list(query);
}
}
测试结果说明: 添加和查询可以正藏使用mybatis-plus的api,删除和更新时会报错:
// 这个是删除的报错
DB::Exception: Syntax error: failed at position 1 ('DELETE'):
DELETE FROM tb_stat WHERE id='10'.
// 这个是更新的报错
DB::Exception: Syntax error: failed at position 1 ('UPDATE') (line 1, col 1):
UPDATE tb_stat SET region='222',group='222',yesterday=222,today=222,stat_date='2020-03-25 12:13:00' WHERE id='4'.
报错的原因说明: clickhouse 数据库的语法有一些不同:
-- 删除语法
alter table tb_stat delete WHERE id='10';
-- 修改语法
alter table tb_stat update today=222 WHERE id='4';
所以删除和修改的SQL要自己在xml文件内写。
4.clickhouse应用场景(copy):
1.绝大多数请求都是用于读访问的 2.数据需要以大批次(大于1000行)进行更新,而不是单行更新;或者根本没有更新操作 3.数据只是添加到数据库,没有必要修改 4.读取数据时,会从数据库中提取出大量的行,但只用到一小部分列 5.表很“宽”,即表中包含大量的列 6.查询频率相对较低(通常每台服务器每秒查询数百次或更少) 7.对于简单查询,允许大约50毫秒的延迟 8.列的值是比较小的数值和短字符串(例如,每个URL只有60个字节) 9.在处理单个查询时需要高吞吐量(每台服务器每秒高达数十亿行) 10.不需要事务 11.数据一致性要求较低 12.每次查询中只会查询一个大表。除了一个大表,其余都是小表 13.查询结果显著小于数据源。即数据有过滤或聚合。返回结果不超过单个服务器内存大小
5.总结
SpringBoot 集成 clickhouse 并使用持久层框架mybatis-plus还是比较容易的,但是 clickhouse 数据库的语法有所不同,mybatis-plus的部分api无法使用需要自己书写。