在springboot中如何集成clickhouse进行读写操作

 更新时间:2024年11月18日 09:41:08   作者:oNuoyi  
本文介绍了在Spring Boot中集成ClickHouse的步骤,包括引入依赖、配置数据源、编写实体类和Mapper类进行CRUD操作,特别提到批量插入时需要在SQL语句中添加`FORMAT`以避免错误,在实际应用中,与MySQL的操作类似,只需将ClickHouse当作MySQL使用

上篇文章讲了如何在docker中搭建clickhouse,本篇记录一下在springboot中如何集成clickhouse并进行读写

1、引入依赖

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3.4</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--升级 druid驱动 1.1.10支持ClickHouse-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.13</version>
        </dependency>

2、编写数据源配置

@Configuration
public class DruidConfig {

    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl("jdbc:clickhouse://localhost:8123/test");
        dataSource.setInitialSize(10);
        dataSource.setMaxActive(100);
        dataSource.setMinIdle(10);
        dataSource.setMaxWait(-1);
        return dataSource;
    }

}

3、编写表实体类

和mysql一模一样写法,对应的表我通过DBeaver已经创建好了

package cn.yufire.sync.sls.getway.logs.pojo;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;

import java.io.Serializable;

@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "getway_logs")
@Data
public class GetwayLogs implements Serializable {
    /**
     * id
     */
    @TableField(value = "id")
    private Long id;

    /**
     * 接口名称:网关上定义的名称
     */
    @TableField(value = "api_name")
    private String apiName;

    /**
     * 响应体
     */
    @TableField(value = "response_body")
    private String responseBody;

    /**
     * 调用环境:TEST、RELEASE、PRE
     */
    @TableField(value = "api_stage_name")
    private String apiStageName;

    /**
     * 错误码
     */
    @TableField(value = "error_code")
    private String errorCode;

    /**
     * 请求类型
     */
    @TableField(value = "http_method")
    private String httpMethod;

    /**
     * 接口请求地址
     */
    @TableField(value = "api_path")
    private String apiPath;

    /**
     * 接口请求全地址
     */
    @TableField(value = "api_full_path")
    private String apiFullPath;

    /**
     * 请求时间
     */
    @TableField(value = "request_time")
    private String requestTime;

    /**
     * 请求体
     */
    @TableField(value = "request_body")
    private String requestBody;

    /**
     * 网关请求阿里云创建
     */
    @TableField(value = "getway_request_id")
    private String getwayRequestId;

    /**
     * 阿里云网关应用id
     */
    @TableField(value = "getway_app_id")
    private String getwayAppId;

    /**
     * 请求协议,HTTP、HTTPS、...
     */
    @TableField(value = "request_protocol")
    private String requestProtocol;

    /**
     * 客户端调用产生的随机字符串
     */
    @TableField(value = "client_nonce")
    private String clientNonce;

    /**
     * 网关应用名称
     */
    @TableField(value = "getway_app_name")
    private String getwayAppName;

    /**
     * 网关分组id
     */
    @TableField(value = "getway_group_id")
    private String getwayGroupId;

    /**
     * 客户端ip
     */
    @TableField(value = "client_ip")
    private String clientIp;

    /**
     * 网关绑定域名
     */
    @TableField(value = "getway_bind_domain")
    private String getwayBindDomain;

    /**
     * 请求体大小
     */
    @TableField(value = "request_size")
    private Integer requestSize;

    /**
     * 响应体大小
     */
    @TableField(value = "response_size")
    private Integer responseSize;

    /**
     * 后端应用响应HTTP状态码
     */
    @TableField(value = "app_response_code")
    private Integer appResponseCode;

    /**
     * 分组名称
     * */
    @TableField(value = "apiGroupName")
    private String apiGroupName;
}

4、创建一个mapper类进行增删改查

因为我使用clickhouse只需要批量插入,所以就写了一个批量插入的sql,当然mybatis-plus也有自带的批量插入的方法,但是不是一条sql执行的,而是通过批量执行多条 SQL 语句来实现的,所以就手写了一个批次插入的sql,这里有一个坑,批量插入clickhouse会报错,单条插入没问题,百度了发现批量插入各种小问题,需要在 Values前加一个FORMAT ,即 insert into x(xx,xx) FORMAT Values (),处理后就没有报错了

package cn.yufire.sync.sls.getway.logs.mapper;

import cn.yufire.sync.sls.getway.logs.pojo.GetwayLogs;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Insert;

import java.util.List;

public interface GetwayLogsMapper extends BaseMapper<GetwayLogs> {

    /**
     * 批量插入网关日志
     *
     * @param list 数据
     * @return
     */
    @Insert("<script>insert into getway_logs(" +
            "api_name," +
            "response_body," +
            "api_stage_name," +
            "error_code," +
            "http_method," +
            "api_path," +
            "api_full_path," +
            "request_time," +
            "request_body," +
            "getway_request_id," +
            "getway_app_id," +
            "request_protocol," +
            "client_nonce," +
            "getway_app_name," +
            "getway_group_id," +
            "client_ip," +
            "getway_bind_domain," +
            "request_size," +
            "response_size," +
            "app_response_code" +
            ") FORMAT Values " +
            " <foreach collection=\"list\" item=\"item\" index=\"index\" separator=\",\">\n" +
            "     (" +
            "#{item.apiName}," +
            "#{item.responseBody}," +
            "#{item.apiStageName}," +
            "#{item.errorCode}," +
            "#{item.httpMethod}," +
            "#{item.apiPath}," +
            "#{item.apiFullPath}," +
            "#{item.requestTime}," +
            "#{item.requestBody}," +
            "#{item.getwayRequestId}," +
            "#{item.getwayAppId}," +
            "#{item.requestProtocol}," +
            "#{item.clientNonce}," +
            "#{item.getwayAppName}," +
            "#{item.getwayGroupId}," +
            "#{item.clientIp}," +
            "#{item.getwayBindDomain}," +
            "#{item.requestSize}," +
            "#{item.responseSize}," +
            "#{item.appResponseCode}" +
            ")\n" +
            "        </foreach>" +

            "</script>")
    Integer batchInsert(List<GetwayLogs> list);


}

在业务中调用

@Autowired
private GetwayLogsMapper getwayLogsMapper;

log.info("批量插入至数据库中...,是否添加成功:{}", getwayLogsMapper.batchInsert(logs));

可以看到增删改查操作和操作mysql的一模一样,也就是说给clickhouse当成mysql用就行

在springboot中集成clickhouse中也遇到了一些报错

ClickHouse exception, code: 1002

使用了clickhouse的依赖和jpa依赖总是跑不起来,一直报没有驱动,给了驱动也不对

clickhouse集成springboot报错Unable to determine Dialect to use [name=ClickHouse, majorVersion=22]; user must register resolver or explicitly set 'hibernate.dialect'

百度了各种最后看到这个,直接给clickhouse的依赖和jpa的依赖去掉就给clickhouse当成mysql结果就正常了

在docker中搭建部署clickhouse教程

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 迅速掌握Java容器中常用的ArrayList类与Vector类用法

    迅速掌握Java容器中常用的ArrayList类与Vector类用法

    这篇文章主要介绍了Java容器中常用的ArrayList类与Vector类用法,文中只对其最基本的功能给出了示例代码,需要的朋友可以参考下
    2015-11-11
  • Java实现的自定义迭代器功能示例

    Java实现的自定义迭代器功能示例

    这篇文章主要介绍了Java实现的自定义迭代器功能,结合具体实例形式分析了java简单迭代器的实现步骤与相关操作技巧,需要的朋友可以参考下
    2017-04-04
  • Java实体类之间的相互转换方式

    Java实体类之间的相互转换方式

    这篇文章主要介绍了Java实体类之间的相互转换方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • java实现画图板功能

    java实现画图板功能

    这篇文章主要为大家详细介绍了java实现画图板功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-09-09
  • JAVA使用Ldap操作AD域的方法示例

    JAVA使用Ldap操作AD域的方法示例

    这篇文章主要介绍了JAVA使用Ldap操作AD域的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • springboot 动态数据源的实现方法(Mybatis+Druid)

    springboot 动态数据源的实现方法(Mybatis+Druid)

    这篇文章主要介绍了springboot 动态数据源的实现方法(Mybatis+Druid),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • java 操作gis geometry类型数据方式

    java 操作gis geometry类型数据方式

    这篇文章主要介绍了java 操作gis geometry类型数据方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • 基于SpringBoot实现图片上传与显示

    基于SpringBoot实现图片上传与显示

    这篇文章主要为大家详细介绍了基于SpringBoot实现图片上传与显示,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • java加载properties文件的六种方法总结

    java加载properties文件的六种方法总结

    这篇文章主要介绍了java加载properties文件的六种方法总结的相关资料,需要的朋友可以参考下
    2017-05-05
  • Java中比较器Comparator和Comparable的区别

    Java中比较器Comparator和Comparable的区别

    这篇文章主要介绍了Java中比较器Comparator和Comparable的区别,我们在使用 Collections.sort()对链表进行排序时,常常需要根据不同情况自定义排序规则,今天我们来看看比较器之间的区别,需要的朋友可以参考下
    2023-08-08

最新评论