spring boot学习第十八篇:使用clickhouse

1、pom.xml文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>org.example</groupId>
    <artifactId>clickhouse-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <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>



</project>

2、application.yml文件内容如下:

server:
  port: 7010

  # mybatis 配置
mybatis:
  type-aliases-package: org.example.entity
  mapper-locations: classpath:/mapper/*.xml

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    click:
      driverClassName: ru.yandex.clickhouse.ClickHouseDriver
      url: jdbc:clickhouse://43.138.0.199:8123/default
      username: default
      password: 123456
      initialSize: 10
      maxActive: 100
      minIdle: 10
      maxWait: 6000

3、UserInfoMapper.xml文件内容如下:

<?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="org.example.mapper.UserInfoMapper">
    <resultMap id="BaseResultMap" type="org.example.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="org.example.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>

4、App.java文件内容如下:

package org.example;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(basePackages = {"org.example.mapper"})
public class App {

    public static void main(String[] args) {
        SpringApplication.run(App.class,args);
    }

}


5、连接配置

package org.example.util;

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;
    }
}


package org.example.util;

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;
    }

}



6、service代码如下:

package org.example.service;

import org.example.entity.UserInfo;
import org.example.mapper.UserInfoMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@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、mapper代码如下:

package org.example.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.example.entity.UserInfo;

import java.util.List;

@Mapper
public interface UserInfoMapper {
    void saveData (UserInfo userInfo) ;
    UserInfo selectById (@Param("id") Integer id) ;
    List<UserInfo> selectList () ;
}

8、UserInfo代码如下:

package org.example.entity;

public class UserInfo {
    private int id;

    private String userName;

    private String passWord;

    private String phone;

    private String createDay;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getCreateDay() {
        return createDay;
    }

    public void setCreateDay(String createDay) {
        this.createDay = createDay;
    }
}

9、controller代码如下:

package org.example.controller;

import org.example.entity.UserInfo;
import org.example.service.UserInfoService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

@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() ;
    }

}


10、启动APP,验证

10.1、访问http://localhost:7010/getById?id=1

查看数据库的数据

代码见:GitHub - veminhe/clickhouse-test

<think>好的,我现在需要帮助用户在Spring Boot项目中配置MyBatis-Plus来连接ClickHouse,并且设置打印SQL的功能。用户还提到了使用baomidou.mybatisplus依赖,所以我要确保引用的依赖正确。此外,用户引用了之前的回答中的一些配置,比如P6Spy驱动和分页插件,可能需要参考这些内容。 首先,我需要确认MyBatis-Plus是否支持ClickHouse。根据经验,MyBatis-Plus主要针对传统关系型数据库,但ClickHouse也有JDBC驱动,所以理论上可以通过配置数据源来连接。用户之前的问题中提到了使用MySQL的驱动,但这里需要替换为ClickHouse的JDBC驱动。 然后,打印SQL通常可以通过MyBatis-Plus的日志配置或者使用P6Spy这样的第三方库来实现。用户之前的引用中提到了P6Spy的配置,这可能是一个可行的方法。需要确认MyBatis-Plus是否兼容P6Spy,以及如何正确配置。 接下来,需要整理步骤: 1. 添加必要的依赖,包括MyBatis-Plus、ClickHouse JDBC驱动、以及P6Spy(如果需要)。 2. 配置数据源,指定ClickHouse的连接信息,并设置driver-class-name为P6Spy的驱动,以便拦截SQL。 3. 配置MyBatis-Plus的分页插件和其他必要组件,如用户之前提到的分页插件配置。 4. 开启MyBatis-Plus的SQL日志,或者在P6Spy的配置文件中设置日志输出。 5. 可能还需要处理一些特定的配置,比如重试机制,用户之前引用了@Retryable,但当前问题可能不需要,但可以作为额外提示。 需要注意的点: - ClickHouse的JDBC驱动类名是否正确。 - P6Spy的配置是否正确,尤其是url的格式是否正确(jdbc:p6spy:clickhouse://...)。 - 日志级别是否正确设置,确保SQL语句能被打印出来。 - 分页插件是否需要针对ClickHouse进行特殊配置,虽然用户的问题主要是打印SQL,但用户之前配置了MySQL的分页插件,可能需要调整。 另外,用户可能遇到驱动不兼容的问题,或者SQL语法的问题,需要提示常见错误和解决方法。例如,ClickHouse和MySQL的语法差异,可能需要自定义SQL模板或拦截器。 最后,验证配置是否生效,可以通过执行一个简单的查询,查看控制台是否有SQL日志输出。如果有问题,检查依赖版本、配置文件的正确性,以及日志配置是否合理。</think>根据引用内容结合MyBatis-Plus特性,Spring Boot整合ClickHouse并实现SQL打印的完整配置如下: --- ### 一、核心依赖配置(pom.xml) ```xml <!-- ClickHouse JDBC驱动 --> <dependency> <groupId>ru.yandex.clickhouse</groupId> <artifactId>clickhouse-jdbc</artifactId> <version>0.3.2</version> </dependency> <!-- MyBatis-Plus核心 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> </dependency> <!-- SQL打印监控(引用[2][3]优化) --> <dependency> <groupId>p6spy</groupId> <artifactId>p6spy</artifactId> <version>3.9.1</version> </dependency> ``` --- ### 二、数据源配置(application.yml) ```yaml spring: datasource: driver-class-name: com.p6spy.engine.spy.P6SpyDriver # 启用SQL拦截 url: jdbc:p6spy:clickhouse://localhost:8123/db_name username: default password: main: allow-bean-definition-overriding: true # 解决分页插件冲突 # MyBatis-Plus原生SQL打印(双重保障) mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl ``` --- ### 三、P6Spy增强配置(spy.properties) ```properties modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory appender=com.p6spy.engine.spy.appender.Slf4JLogger logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger deregisterdrivers=true useprefix=true excludecategories=info,debug,result,resultset outagedetection=true outagedetectioninterval=2 ``` --- ### 四、MyBatis-Plus插件配置类 ```java @Configuration public class MyBatisConfig { /** * 分页插件(引用[3]升级版) */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // ClickHouse专用分页(需注意语法差异) interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.CLICK_HOUSE){ @Override protected String getCountOptimizeSql(String originalSql, long count) { return "SELECT count() FROM (" + originalSql + ") _mp_count"; } }); return interceptor; } /** * 性能分析插件(开发环境开启) */ @Profile({"dev", "test"}) @Bean public PerformanceInterceptor performanceInterceptor() { PerformanceInterceptor interceptor = new PerformanceInterceptor(); interceptor.setFormat(true); // 格式化SQL输出 interceptor.setMaxTime(1000); // 超过1秒的SQL记录警告 return interceptor; } } ``` --- ### 五、SQL打印效果验证 执行查询后控制台输出: ```sql Consume Time:5ms 2023-07-20 14:00:00 SQL:SELECT id,name FROM user WHERE age > 18 LIMIT 10 ``` --- ### 六、常见问题解决 1. **驱动冲突**:若出现`No suitable driver`错误,检查URL格式是否正确: ```yaml url: jdbc:p6spy:clickhouse://host:port/db # P6Spy代理格式 ``` 2. **分页异常**:ClickHouse需自定义分页拦截器(参考第四步配置) 3. **日志重复输出**:关闭MyBatis原生日志保留P6Spy输出 ```yaml mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl ``` --- ### 七、扩展优化建议 1. **重试机制**:结合引用[4]添加ClickHouse连接重试 ```java @EnableRetry public class RetryConfig { @Retryable(value = ClickHouseException.class, maxAttempts = 3) public void chQuery() { // 数据库操作 } } ``` 2. **监控集成**:通过`spring-boot-starter-actuator`暴露/datasource端点监控连接池状态 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值