SpringBoot整合ClickHouse

news2024/11/16 3:28:07

目录

  • 1 ClickHouse准备操作
  • 2 使用jdbc方式操作ClickHouse
  • 3 SpringBoot的整合ClickHouse


1 ClickHouse准备操作

在这里插入图片描述

使用的JDBC方式操作clickhouseclickhouse与springboot的整合使用

提前创建一张表,并为该表插入一些实验数据

create table t_order01(
 id UInt32,
 sku_id String,
 total_amount Decimal(16,2),
 create_time Datetime
) engine =MergeTree
 partition by toYYYYMMDD(create_time)
 primary key (id)
 order by (id,sku_id);
 
insert into t_order01 values
(101,'sku_001',1000.00,'2021-12-01 12:00:00'),
(102,'sku_002',2000.00,'2021-12-01 11:00:00'),
(102,'sku_004',2500.00,'2021-12-01 12:00:00'),
(102,'sku_002',2000.00,'2021-12-01 13:00:00'),
(102,'sku_002',12000.00,'2021-12-01 13:00:00'),
(102,'sku_002',600.00,'2020-06-12 12:00:00');

2 使用jdbc方式操作ClickHouse

1、引入clickhouse的jdbc依赖

<dependency>
    <groupId>ru.yandex.clickhouse</groupId>
    <artifactId>clickhouse-jdbc</artifactId>
    <version>0.1.52</version>
</dependency>

2、实例代码

实大部分的操作和我们使用jdbc操作mysql的步骤类似,下面直接贴出代码,可以结合注释进行参考使用

import oldlu.clickhouse.ClickHouseConnection;
import oldlu.clickhouse.ClickHouseDataSource;
import oldlu.clickhouse.settings.ClickHouseProperties;
 
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class CreateTableTest {
 
    private static String username = "default";
    private static String password = "你的连接密码";
    private static String address = "jdbc:clickhouse://clickhouse的连接IP地址:8123";
    private static String db = "连接数据库名称(默认数据库:default)";
    private static int socketTimeout = 600000;
 
    public static void main(String[] args) throws Exception {
        //getConn();
        //queryTable();
        //createTable("");
        //insertOne();
        //dropTable();
        deleteById();
        //updateById();
    }
 
    /**
     * 查询数据
     */
    public static void queryTable(){
        List<Map<String, Object>> list = new ArrayList<>();
        String sql = "select * from user_info";
        Connection connection = getConn();
        try {
            Statement statement = connection.createStatement();
            ResultSet rs  = statement.executeQuery(sql);
            ResultSetMetaData rsmd = rs.getMetaData();
            while(rs.next()){
                Map<String, Object> row = new HashMap<>();
                for(int i = 1; i <= rsmd.getColumnCount(); i++){
                    row.put(rsmd.getColumnName(i), rs.getObject(rsmd.getColumnName(i)));
                }
                list.add(row);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
 
        //在此可以根据实际需求将解析的数据封装到对象中
        list.stream().forEach(item ->{
            Map<String, Object> rowData = item;
            System.out.println(rowData);
        });
        //System.out.println(list);
    }
 
    /**
     * 创建表
     * @throws Exception
     */
    public static void createTable(String tableSql) throws Exception{
        /*tableSql = "create table t_order02(\n" +
                " id UInt32,\n" +
                " sku_id String,\n" +
                " total_amount Decimal(16,2),\n" +
                " create_time Datetime\n" +
                ") engine =MergeTree\n" +
                " partition by toYYYYMMDD(create_time)\n" +
                " primary key (id)\n" +
                " order by (id,sku_id);";*/
        Connection connection = getConn();
        Statement statement = connection.createStatement();
        boolean execute = statement.execute(tableSql);
        if(execute){
            System.out.println(execute);
            System.out.println("创建表成功");
        }
    }
 
    /**
     * 删除表
     * @throws Exception
     */
    public static void dropTable() throws Exception{
        Connection connection = getConn();
        Statement statement = connection.createStatement();
        statement.execute("drop table t_order01;");
        System.out.println("删除表成功");
    }
 
    /**
     * 插入数据
     * 实际使用时候,插入的语句里面的参数从外部传入进去
     * @throws Exception
     */
    public static void insertOne() throws Exception{
        Connection connection = getConn();
        PreparedStatement pstmt = connection.prepareStatement("insert into t_order01 values('103', 'sku_004', '2500.00','2021-06-01 12:00:00')");
        pstmt.execute();
        System.out.println("insert success");
    }
 
    /**
     * 删除数据
     * 实际使用时候,删除的语句里面的参数从外部传入进去
     */
    public static void deleteById() throws Exception{
        Connection connection = getConn();
        //sku_id ='sku_001'
        PreparedStatement pstmt = connection.prepareStatement("alter table t_order01 delete where sku_id = 'sku_002';");
        pstmt.execute();
        System.out.println("delete success");
    }
 
    /**
     * 修改数据
     * 实际使用时候,修改的语句里面的参数从外部传入进去
     */
    public static void updateById() throws Exception{
        Connection connection = getConn();
        PreparedStatement pstmt = connection.prepareStatement("alter table t_order01 update total_amount=toDecimal32(2000.00,2) where id = '102'");
        pstmt.execute();
        System.out.println("update success");
    }
 
    public static Connection getConn() {
        ClickHouseProperties properties = new ClickHouseProperties();
        properties.setUser(username);
        properties.setPassword(password);
        properties.setDatabase(db);
        properties.setSocketTimeout(socketTimeout);
        ClickHouseDataSource clickHouseDataSource = new ClickHouseDataSource(address, properties);
        ClickHouseConnection conn = null;
        try {
            conn = clickHouseDataSource.getConnection();
            System.out.println(conn);
            System.out.println("连接成功");
            return conn;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}

3、测试,选择查询和删除一条数据为例做测试

查询功能测试结果,见下面的控制台数据打印

在这里插入图片描述

删除功能测试结果,删除 "sku_id = sku_002 "的数据, 执行方法之后,见下面的控制台数据打印

在这里插入图片描述

3 SpringBoot的整合ClickHouse

在实际开发过程中,更多是与框架整合在一起进行使用,比如很多项目中都使用springboot进行开发,下面演示如何在springboot中使用clickhouse

前置准备

确保clickhouse服务正常可用

1、准备一张表,以及表中插入一些实验数据

CREATE TABLE user_info (
  `id` UInt64,
  `user_name` String,
  `pass_word` String,
  `phone` String,
  `create_day` Date DEFAULT CAST(now(),'Date')
)ENGINE = MergeTree
primary key (id)
order by (id);
 
 
INSERT INTO user_info
  (id,user_name,pass_word,phone)
VALUES
  (1,'xiaowang','123456','13325511231'),
  (2,'xiaoma','123456','13825511231'),
  (3,'xiaozhao','123456','18925511231');

2、执行完毕上面的建表后,查询下表数据

在这里插入图片描述

1、导入完整依赖

<dependencies>
 
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
 
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
 
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
 
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.38</version>
    </dependency>
 
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.13</version>
    </dependency>
 
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.6</version>
    </dependency>
 
    <!-- clickHouse数据库 -->
    <dependency>
        <groupId>ru.yandex.clickhouse</groupId>
        <artifactId>clickhouse-jdbc</artifactId>
        <version>0.1.53</version>
    </dependency>
 
</dependencies>

2、基础配置文件

server:
  port: 7010
 
  # mybatis 配置
mybatis:
  type-aliases-package: com.congge.entity
  mapper-locations: classpath:/mapper/*.xml
 
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    click:
      driverClassName: ru.yandex.clickhouse.ClickHouseDriver
      url: jdbc:clickhouse://IP地址:8123/default
      username: default
      password: 123456
      initialSize: 10
      maxActive: 100
      minIdle: 10
      maxWait: 6000

3、使用一个配置类,关联第二步中的click配置属性

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
 
@Component
@ConfigurationProperties(prefix = "spring.datasource.click")
public class ConnectionParamConfig {
 
    private String driverClassName ;
    private String url ;
    private Integer initialSize ;
    private Integer maxActive ;
    private Integer minIdle ;
    private Integer maxWait ;
 
    private String username;
    private String password;
 
    public String getDriverClassName() {
        return driverClassName;
    }
    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public Integer getInitialSize() {
        return initialSize;
    }
    public void setInitialSize(Integer initialSize) {
        this.initialSize = initialSize;
    }
    public Integer getMaxActive() {
        return maxActive;
    }
    public void setMaxActive(Integer maxActive) {
        this.maxActive = maxActive;
    }
    public Integer getMinIdle() {
        return minIdle;
    }
    public void setMinIdle(Integer minIdle) {
        this.minIdle = minIdle;
    }
    public Integer getMaxWait() {
        return maxWait;
    }
    public void setMaxWait(Integer maxWait) {
        this.maxWait = maxWait;
    }
 
    public String getUsername() {
        return username;
    }
 
    public void setUsername(String username) {
        this.username = username;
    }
 
    public String getPassword() {
        return password;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
}

4、重写datasource的配置,使用自定义的clickhouse的属性配置

import javax.annotation.Resource;
 
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import javax.sql.DataSource;
 
@Configuration
public class DruidConfig {
 
    @Resource
    private ConnectionParamConfig jdbcParamConfig;
 
    /**
     * 重写 DataSource
     * @return
     */
    @Bean
    public DataSource dataSource() {
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(jdbcParamConfig.getUrl());
        datasource.setDriverClassName(jdbcParamConfig.getDriverClassName());
        datasource.setInitialSize(jdbcParamConfig.getInitialSize());
        datasource.setMinIdle(jdbcParamConfig.getMinIdle());
        datasource.setMaxActive(jdbcParamConfig.getMaxActive());
        datasource.setMaxWait(jdbcParamConfig.getMaxWait());
        datasource.setUsername(jdbcParamConfig.getUsername());
        datasource.setPassword(jdbcParamConfig.getPassword());
        return datasource;
    }
 
}

5、提供一个接口和mybatis的查询xml文件

public interface UserInfoMapper {
    void saveData (UserInfo userInfo) ;
    UserInfo selectById (@Param("id") Integer id) ;
    List<UserInfo> selectList () ;
}
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.congge.mapper.UserInfoMapper">
    <resultMap id="BaseResultMap" type="com.congge.entity.UserInfo">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="user_name" jdbcType="VARCHAR" property="userName" />
        <result column="pass_word" jdbcType="VARCHAR" property="passWord" />
        <result column="phone" jdbcType="VARCHAR" property="phone" />
        <result column="create_day" jdbcType="VARCHAR" property="createDay" />
    </resultMap>
 
    <sql id="Base_Column_List">
        id,user_name,pass_word,phone,create_day
    </sql>
 
    <insert id="saveData" parameterType="com.congge.entity.UserInfo" >
        INSERT INTO user_info
        (id,user_name,pass_word,phone,create_day)
        VALUES
        (#{id,jdbcType=INTEGER},#{userName,jdbcType=VARCHAR},#{passWord,jdbcType=VARCHAR},
        #{phone,jdbcType=VARCHAR},#{createDay,jdbcType=VARCHAR})
    </insert>
 
    <select id="selectById" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from user_info
        where id = #{id,jdbcType=INTEGER}
    </select>
 
    <select id="selectList" resultMap="BaseResultMap" >
        select
        <include refid="Base_Column_List" />
        from user_info
    </select>
 
</mapper>

6、Service

@Service
public class UserInfoService {
 
    @Resource
    private UserInfoMapper userInfoMapper ;
 
    public void saveData(UserInfo userInfo) {
        userInfoMapper.saveData(userInfo);
    }
 
    public UserInfo selectById(Integer id) {
        return userInfoMapper.selectById(id);
    }
 
    public List<UserInfo> selectList() {
        return userInfoMapper.selectList();
    }
 
}

7、Controller

@RestController
public class UserInfoController {
 
    @Resource
    private UserInfoService userInfoService ;
 
    //localhost:7010/saveData
    @GetMapping("/saveData")
    public String saveData (){
        UserInfo userInfo = new UserInfo () ;
        userInfo.setId(4);
        userInfo.setUserName("xiaolin");
        userInfo.setPassWord("54321");
        userInfo.setPhone("18500909876");
        userInfo.setCreateDay("2022-02-06");
        userInfoService.saveData(userInfo);
        return "success";
    }
 
    //localhost:7010/getById?id=1
    @GetMapping("/getById")
    public UserInfo getById (int id) {
        return userInfoService.selectById(id) ;
    }
 
    @GetMapping("/getList")
    public List<UserInfo> getList () {
        return userInfoService.selectList() ;
    }
 
}

8、启动类

@SpringBootApplication
@MapperScan(basePackages = {"com.congge.mapper"})
public class App {
 
    public static void main(String[] args) {
        SpringApplication.run(App.class,args);
    }
 
}

9、功能接口测试

查询测试,调用接口:localhost:7010/getById?id=1

在这里插入图片描述

插入数据测试,调用接口:localhost:7010/saveData

在这里插入图片描述

然后再去clickhouse表中查询下数据

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/447503.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

卡片+递增三元组——蓝桥杯(JAVA解法)

1、卡片 题目链接&#xff1a;用户登录https://www.lanqiao.cn/problems/2383/learning/?page5&first_category_id1&sortstudents_count 问题描述 小蓝有 k 种卡片, 一个班有 n 位同学, 小蓝给每位同学发了两张卡片, 一 位同学的两张卡片可能是同一种, 也可能是不同…

xubuntu16.04下安装向日葵并设置开机自启

1.安装Sunlogin 下载 SunloginClient-11.0.1.44968-amd64.deb 解压后将SunloginClient-11.0.1.44968-amd64.deb拷贝到目标设备上&#xff0c;终端运行&#xff1a; dpkg -i SunloginClient-11.0.1.44968-amd64.deb进入到\usr/local/sunlogin/bin目录下&#xff0c;运行向日葵…

第一章 Maven概述

第一节 为什么要学习Maven&#xff1f; maven-作为依赖管理工具 ①jar 包的规模 随着我们使用越来越多的框架&#xff0c;或者框架封装程度越来越高&#xff0c;项目中使用的jar包也越来越多。项目中&#xff0c;一个模块里面用到上百个jar包是非常正常的。 比如下面的例子…

FreeRTOS 队列(二)

文章目录 一、向队列发送消息1. 函数原型&#xff08;1&#xff09;函数 xQueueOverwrite()&#xff08;2&#xff09;函数 xQueueGenericSend()&#xff08;3&#xff09;函数 xQueueSendFromISR()、xQueueSendToBackFromISR()、xQueueSendToFrontFromISR()&#xff08;4&…

GIT的常见命令

前言&#xff1a; 在日常生活或者工作中&#xff0c;我们都会是不是用到Git&#xff0c;今天我就总结了一些Git常见命令。若有些木有的&#xff0c;可以使用git help 获取到git的常见命令&#xff0c;那我们接下来就从git help 中的介绍常见命令。 一&#xff1a;建立本地仓库…

TCP 与 bufferbloat

说到既能降低成本&#xff0c;又能降低时延&#xff0c;总觉得这在 pr&#xff0c;兜售自己或卖东西。毕竟哪有这么好的事&#xff0c;鱼与熊掌兼得。可事实上是人们对 buffer 的理解错了才导致了这种天上掉馅饼的事发生。 人们总觉得 buffer 越大越好&#xff0c;buffer 越大…

Maven安装教程以及修改下载镜像源等配置

第一步&#xff1a;下载maven&#xff08;本教程安装的是3.8.4&#xff09; 官方下载链接&#xff1a;Maven – Download Apache Maven Binary是可执行版本&#xff0c;已经编译好可以直接使用。 Source是源代码版本&#xff0c;需要自己编译成可执行软件才可使用。 我们选择…

【WSN定位】基于RSSI的加权质心定位算法【Matlab代码#14】

文章目录 1. 原始质心定位算法2. 基于RSSI的加权质心定位算法基本思想3. 基于RSSI的加权质心定位算法流程图4. 部分代码展示5. 运行结果展示6. 资源获取 1. 原始质心定位算法 可参考质心定位算法 2. 基于RSSI的加权质心定位算法基本思想 传统的质心算法在求解过程中只是将未…

Windows逆向安全(一)之基础知识(十六)

指针三 通过先前指针的学习&#xff0c;了解了指针和地址以及数据的关系&#xff0c;现在结合先前的知识继续学习巩固 指针遍历数组 有了先前的基础&#xff0c;再来看看如何用指针遍历数组 代码 #include "stdafx.h" void function(){short arr[5]{1,2,3,4,5};…

【ARM Coresight 4 - Rom Table 介紹】

文章目录 1.1 ROM Table1.1.1 Entry 寄存器 1.2 ROM Table 例子 1.1 ROM Table 在一个SoC中&#xff0c;有多个Coresight 组件&#xff0c;但是软件怎么去识别这些 Coresight 组件&#xff0c;去获取这些Coresight 组件的信息了&#xff1f;这个时候&#xff0c;就需要靠 Core…

COPU助力北大研究生开源公选课丨2023开源PostgreSQL内核开发通识课顺

COPU & Peking Univerisity 导读&#xff1a;2020年1月COPU&#xff08;中国开源软件推进联盟&#xff09;成员开会讨论面向高校的开源示范课程&#xff0c;由联盟副秘书长北京大学荆琦老师牵头筹备&#xff0c;并首先在北大软微学院试点。本次是中国PostgreSQL分会联合…

尚硅谷_宋红康_第14章_数据结构与集合源码

第14章_数据结构与集合源码 本章专题与脉络 1. 数据结构剖析 我们举一个形象的例子来理解数据结构的作用&#xff1a; [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bgDcr8wF-1682075329317)(images/image-20220412011531879.png)] **战场&#x…

本地白嫖AI绘画 ,Stable Diffusion 初探!

本文介绍我在本地搭建 Stable Diffusion Web UI 的体验过程&#xff0c;予以记录分享。 Stable Diffusion 是 2022 年 8 发布的深度学习文本到图像生成模型。它主要用于根据文本的描述产生详细图像&#xff0c;官方项目其实并不适合新手直接使用&#xff0c;好在有使用 Stable …

把握数字中国建设重大契机,实在智能携手山东商业职业技术学院共建“现代金融数字化实训中心”

今年2月&#xff0c;中共中央、国务院印发《数字中国建设整体布局规划》&#xff08;以下简称《规划》&#xff09;&#xff0c;明确了数字中国建设的整体框架&#xff0c;强调全面提升数字中国建设的整体性、系统性、协同性&#xff0c;促进数字经济和实体经济深度融合。其中&…

本地部署Stable Diffusion Webui AI 记录

Stable Diffusion Webui AI本地部署基本分为两种方式&#xff1a; 1、使用大佬的打包好的安装包一键部署 b站秋葉aaaki 2、手动部署&#xff08;个人实践记录&#xff09;参考文章 本地部署基本要求 1、 需要拥有NVIDIA显卡&#xff0c;GTX1060 &#xff08;或者同等算力的…

CopyOnWriteArrayList简介

1. 简介 CopyOnWriteArrayList 是 ArrayList 的线程安全版本 就是在进行写操作的时候会 copy 原数组&#xff0c;然后写完将指针指向新的数组&#xff0c;是一种读写分离的思想&#xff0c;可以并发的读&#xff0c;不能并发的写 优点&#xff1a; 保证线程安全读取时不加锁…

基于PyQt5的图形化界面开发——自制MQTT客户端软件

基于 PyQt5 的图形化界面开发——自制MQTT客户端 0. 前言1. 第三方库的安装及注意事项2. Editor.py2.1 配置界面效果演示&#xff1a; 3. Publish.py3.1 消息发布界面演示 4. Subcribe.py4.1 订阅消息效果演示&#xff1a; 界面切换——main.py5. 写在最后 0. 前言 使用 PyQt5…

葛兰一季度规模再度跌破900亿

一季度末管理规模再度跌破900亿元&#xff0c;中欧基金葛兰交出了公募主动权益基金管理规模的头把交椅。 4月22日零点刚过&#xff0c;葛兰在管基金悉数披露2023年一季报&#xff0c;从管理规模来看&#xff0c;一季度葛兰在管5只公募基金合计规模降至844.40亿元&#xff0c;较…

keep-alive 和 router-view 的使用方法(Vue3)

系列文章目录 提示&#xff1a;主要是介绍keep-alive 和 router-view在Vue3中的使用方法&#xff0c;以及适用场景&#xff01;&#xff01;&#xff01; 文章目录 系列文章目录前言&#xff1a;一、router-view&#xff1a;1. 常规使用方法2. 非常规使用方法&#xff08;插槽&…

UE5语音识别和语音合成-阿里云智能语音-短视频-翻译-文章-AI角色等

UE5智能语音 哈喽&#xff0c;大家好&#xff0c;我叫人宅&#xff0c;很高兴和大家一起分享本套课程&#xff0c;阿里云智能语音UE5版本开发。阿里云智能语音一共分为 语音合成&#xff0c;语音识别&#xff0c;什么是语音合成&#xff0c;它可以将您的文字转化成您设定的任何…