一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 如何將Mybatis連接到ClickHouse

如何將Mybatis連接到ClickHouse

2021-08-24 10:28空夜 Java教程

這篇文章主要介紹了如何將Mybatis連接到ClickHouse,幫助大家更好得理解和學習使用Mybatis,感興趣的朋友可以了解下

場景

最近在做數據分析項目,里面有這樣一個業務:把匹配的數據打上標簽,放到新的索引中。

數據量:累計億級的數據

使用場景:可能會單次查詢大量的數據,但不會設置復雜的條件,且這些數據不會被再次修改

原來使用的數據庫:ElasticSearch

問題:上面也說了我這里打上標記后,這些數據幾乎不會再修改了。ES 是一個全文檢索引擎,更適用于進行大量文本檢索的情況。這里與我上面的使用場景就不太匹配了。

技術選型的考慮:改用戰斗民族開發的 ClickHouse,它適用于 OLAP 也就是數據分析的場景,當數據寫入后,通過不同維度不斷挖掘、分析,發現其中的商業價值。ClickHouse 適用于讀遠大于寫的情況。

此外,相比ES,ClickHouse 占用的硬盤空間更小,也有利于降低運維成本。

下面是我在嘗試接入 ClickHouse 時的一些實踐,以及關于 ClickHouse數組類型轉換問題的解決方案。

關于 ClickHouse 更詳細的知識參考:https://zhuanlan.zhihu.com/p/98135840

示例代碼已經上傳到了 Git,目前更新第 28 節:https://github.com/laolunsi/spring-boot-examples/

Mybatis + ClickHouse

以前一直用 Mybatis 去操作 MySQL,其實 Mybatis 還可以操作 ClickHouse,這里用 Druid 進行連接管理。

maven 配置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.2.5</version>
</dependency>
 
<dependency>
  <groupId>ru.yandex.clickhouse</groupId>
  <artifactId>clickhouse-jdbc</artifactId>
  <version>0.2.6</version>
</dependency>
 
<dependency>
  <groupId>org.mybatis.spring.boot</groupId>
  <artifactId>mybatis-spring-boot-starter</artifactId>
  <version>2.1.3</version>
</dependency>

配置文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
spring:
 datasource:
  type: com.alibaba.druid.pool.DruidDataSource
 
  # 注意這里是自定義的配置,通過 JdbcParamConfig 來加載配置到 Spring 中
  # 然后由 DruidConfig 來配置數據源
  click:
   driverClassName: ru.yandex.clickhouse.ClickHouseDriver
   url: jdbc:clickhouse://127.0.0.1:8123/test # ip:port/database
   userName: default
   password: default # 按照自己連接的 clickhouse 數據庫來
   initialSize: 10
   maxActive: 100
   minIdle: 10
   maxWait: 6000
   validationQuery: SELECT 1

加載配置項的類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Component
@ConfigurationProperties(prefix = "spring.datasource.click")
public class JdbcParamConfig {
  private String userName;
  private String password;
  private String driverClassName ;
  private String url ;
  private Integer initialSize ;
  private Integer maxActive ;
  private Integer minIdle ;
  private Integer maxWait ;
  private String validationQuery;
 
  // ignore getters and setters
}

配置 Druid:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Configuration
@MapperScan(basePackages = {
    "com.aegis.analysis.clickhousestorage.dao"
})
public class DruidConfig {
  @Resource
  private JdbcParamConfig jdbcParamConfig ;
 
  @Bean(name = "clickDataSource")
  public DataSource dataSource() throws ClassNotFoundException {
    Class classes = Class.forName("com.alibaba.druid.pool.DruidDataSource");
    DruidDataSource dataSource = (DruidDataSource) DataSourceBuilder
        .create()
        .driverClassName(jdbcParamConfig.getDriverClassName())
        .type(classes)
        .url(jdbcParamConfig.getUrl())
        .username(jdbcParamConfig.getUserName())
        .password(jdbcParamConfig.getPassword())
        .build();
    dataSource.setMaxWait(jdbcParamConfig.getMaxWait());
    dataSource.setValidationQuery(jdbcParamConfig.getValidationQuery());
    return dataSource;
  }
 
  @Bean
  public SqlSessionFactory clickHouseSqlSessionFactoryBean() throws Exception {
    SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
    factory.setDataSource(dataSource());
    // 實體 model的 路徑 比如 com.order.model
    factory.setTypeAliasesPackage("com.example.clickhousedemo.model");
    //添加XML目錄
    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    factory.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
    //開啟駝峰命名轉換
    factory.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
    return factory.getObject();
  }
}

定義一個 UserInfo 類,建表語句如下:

?
1
2
3
4
5
6
7
8
9
CREATE TABLE test.user (
   `id` Int16,
   `name` String,
   `score` Float32,
   `score2` Float64,
   `state` Int8,
   `createTime` DateTime,
   `ranks` Array(UInt8)
   ) ENGINE = MergeTree() ORDER BY id;

實體類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class UserInfo {
 
  private Integer id; // int16
  private String name; // String
  private Float score; // float16
  private Double score2; // float32
  private Boolean state; // int8
  private Date createTime; // datetime
  private Integer[] ranks; // Array - Array 類型需要進行類型轉換
  // 具體轉換方法與配置參考 ClickArrayToIntHandler 類與 UserMapper.xml 中關于查詢和插入時 ranks 字段的配置
 
  // ignore getters and setters
}

DAO 和 Mapper 文件就按照連接 MYSQL 時的寫法一樣。

這里有個需要注意的點,ClickHouse 有個 Array 類型,可以用來存數組,就像 ES 一樣。問題是類型轉換需要自己定義。網上一些資料僅列出了基本類型的場景,我自己實現了一個轉換器,可以參考一下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
 * Java Int 數組與 ClockHouse Array Int 轉換器
 * @version 1.0
 * @since 2019/11/14 9:59
 */
public class ClickArrayToIntHandler extends BaseTypeHandler<Integer[]> {
 
  @Override
  public void setNonNullParameter(PreparedStatement preparedStatement, int i, Integer[] integers, JdbcType jdbcType) throws SQLException {
    preparedStatement.setObject(i, integers);
  }
 
  @Override
  public Integer[] getNullableResult(ResultSet resultSet, String s) throws SQLException {
    Object obj = resultSet.getObject(s);
    return parseClickHouseArrayToInt(obj);
  }
 
  @Override
  public Integer[] getNullableResult(ResultSet resultSet, int i) throws SQLException {
    Object obj = resultSet.getObject(i);
    return parseClickHouseArrayToInt(obj);
  }
 
  @Override
  public Integer[] getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
    Object obj = callableStatement.getObject(i);
    return parseClickHouseArrayToInt(obj);
  }
 
  private Integer[] parseClickHouseArrayToInt(Object obj) {
    if (obj instanceof ClickHouseArray) {
      int[] res = new int[0];
      try {
        res = (int[]) ((ClickHouseArray) obj).getArray();
      } catch (SQLException ex) {
        ex.printStackTrace();
      }
 
      if (res != null && res.length > 0) {
        Integer[] resI = new Integer[res.length];
        for (int i = 0; i < res.length; i++) {
          resI[i] = res[i];
        }
 
        return resI;
      }
    }
    return new Integer[0];
  }
}

DAO.xml 也給一個示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?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.aegis.analysis.clickhousestorage.dao.UserInfoMapper">
  <resultMap id="BaseResultMap" type="com.example.clickhousedemo.model.UserInfo">
    <id column="id" property="id" />
    <result column="name" property="name" />
    <result column="name" property="name" />
    <result column="score" property="score" />
    <result column="score2" property="score2" />
    <result column="state" property="state" />
    <result column="createTime" property="createTime" />
    <!-- <result column="ranks" property="ranks" jdbcType="JAVA_OBJECT" javaType="java.lang.Object" />-->
    <result column="ranks" property="ranks" typeHandler="com.example.clickhousedemo.dao.ClickArrayToIntHandler" />
  </resultMap>
 
  <sql id="Base_Column_List">
    *
  </sql>
 
  <insert id="saveData" parameterType="com.aegis.analysis.clickhousestorage.model.UserInfo" >
    INSERT INTO user
      (id,name, score, score2, state, createTime, ranks)
    VALUES
    (#{id},#{name}, #{score}, #{score2}, #{state}, #{createTime}, #{ranks, jdbcType=ARRAY,
    typeHandler=com.example.clickhousedemo.dao.ClickArrayToIntHandler})
  </insert>
 
  <select id="selectById" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from user
    where id = #{id}
    limit 1
  </select>
 
  <select id="selectList" resultMap="BaseResultMap" >
    select
    <include refid="Base_Column_List" />
    from user
  </select>
</mapper>

具體代碼可以去我的 Git 倉庫里查看,還有 SpringBoot 整合其他中間件技術的示例,歡迎 Star!

https://github.com/laolunsi/spring-boot-examples

以上就是如何將Mybatis連接到ClickHouse的詳細內容,更多關于Mybatis連接到ClickHouse的資料請關注服務器之家其它相關文章!

原文鏈接:http://www.eknown.cn/index.php/spring-boot/clickhouse.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: chinese国产打屁股 | 成人影院在线观看免费 | 国内精品 大秀视频 日韩精品 | 精品视频日本 | 国产精品1页 | 午夜精品久久久久久久2023 | 欧美午夜网站 | 精品一区二区三区高清免费观看 | 免费在线观看日韩 | 成人福利网站含羞草 | h网站国产 | 经典三级四虎在线观看 | 99热在线这里只有精品 | 国产成+人+综合+亚洲不卡 | 国产精品久久久久久岛国 | 女人张开腿 让男人桶个爽 免费观看 | 免费在线观看成年人视频 | 四虎在线永久免费视频网站 | 国产精品日韩欧美一区二区 | 91精品久久一区二区三区 | 黑人chinese女人 | 福利视频免费 | 亚洲精品久久久WWW游戏好玩 | 午夜私人福利影院 | 催眠 迷j系列小说 | 亚洲免费大全 | 歪歪视频在线播放无遮挡 | 91系列在线观看免费 | 日本剧情片在线播放中文版 | 国产精品第一区揄拍 | 色老板最新网站视频地址 | 91夜夜操 | 久久精品国产色蜜蜜麻豆国语版 | 国内精品久久久久久久久久久久 | 国产资源视频在线观看 | 秒播影视 午夜福利毛片 | 成人看片免费无限观看视频 | 国产午夜精品久久理论片 | 出轨同学会2在线观看 | 奇米影视小说 | 操b图片|