日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

如何將Mybatis連接到ClickHouse

瀏覽:240日期:2023-10-19 16:26:33
場(chǎng)景

最近在做數(shù)據(jù)分析項(xiàng)目,里面有這樣一個(gè)業(yè)務(wù):把匹配的數(shù)據(jù)打上標(biāo)簽,放到新的索引中。

數(shù)據(jù)量:累計(jì)億級(jí)的數(shù)據(jù)

使用場(chǎng)景:可能會(huì)單次查詢大量的數(shù)據(jù),但不會(huì)設(shè)置復(fù)雜的條件,且這些數(shù)據(jù)不會(huì)被再次修改

原來(lái)使用的數(shù)據(jù)庫(kù):ElasticSearch

問(wèn)題:上面也說(shuō)了我這里打上標(biāo)記后,這些數(shù)據(jù)幾乎不會(huì)再修改了。ES 是一個(gè)全文檢索引擎,更適用于進(jìn)行大量文本檢索的情況。這里與我上面的使用場(chǎng)景就不太匹配了。

技術(shù)選型的考慮:改用戰(zhàn)斗民族開(kāi)發(fā)的 ClickHouse,它適用于 OLAP 也就是數(shù)據(jù)分析的場(chǎng)景,當(dāng)數(shù)據(jù)寫(xiě)入后,通過(guò)不同維度不斷挖掘、分析,發(fā)現(xiàn)其中的商業(yè)價(jià)值。ClickHouse 適用于讀遠(yuǎn)大于寫(xiě)的情況。

此外,相比ES,ClickHouse 占用的硬盤(pán)空間更小,也有利于降低運(yùn)維成本。

下面是我在嘗試接入 ClickHouse 時(shí)的一些實(shí)踐,以及關(guān)于 ClickHouse數(shù)組類型轉(zhuǎn)換問(wèn)題的解決方案。

關(guān)于 ClickHouse 更詳細(xì)的知識(shí)參考:https://zhuanlan.zhihu.com/p/98135840

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

Mybatis + ClickHouse

以前一直用 Mybatis 去操作 MySQL,其實(shí) Mybatis 還可以操作 ClickHouse,這里用 Druid 進(jìn)行連接管理。

maven 配置

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

配置文件:

spring: datasource: type: com.alibaba.druid.pool.DruidDataSource # 注意這里是自定義的配置,通過(guò) JdbcParamConfig 來(lái)加載配置到 Spring 中 # 然后由 DruidConfig 來(lái)配置數(shù)據(jù)源 click: driverClassName: ru.yandex.clickhouse.ClickHouseDriver url: jdbc:clickhouse://127.0.0.1:8123/test # ip:port/database userName: default password: default # 按照自己連接的 clickhouse 數(shù)據(jù)庫(kù)來(lái) initialSize: 10 maxActive: 100 minIdle: 10 maxWait: 6000 validationQuery: SELECT 1

加載配置項(xiàng)的類:

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

@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()); // 實(shí)體 model的 路徑 比如 com.order.model factory.setTypeAliasesPackage('com.example.clickhousedemo.model'); //添加X(jué)ML目錄 ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); factory.setMapperLocations(resolver.getResources('classpath:mapper/*.xml')); //開(kāi)啟駝峰命名轉(zhuǎn)換 factory.getObject().getConfiguration().setMapUnderscoreToCamelCase(true); return factory.getObject(); }}

定義一個(gè) UserInfo 類,建表語(yǔ)句如下:

CREATE TABLE test.user ( `id` Int16, `name` String, `score` Float32, `score2` Float64, `state` Int8, `createTime` DateTime, `ranks` Array(UInt8) ) ENGINE = MergeTree() ORDER BY id;

實(shí)體類:

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 類型需要進(jìn)行類型轉(zhuǎn)換 // 具體轉(zhuǎn)換方法與配置參考 ClickArrayToIntHandler 類與 UserMapper.xml 中關(guān)于查詢和插入時(shí) ranks 字段的配置 // ignore getters and setters}

DAO 和 Mapper 文件就按照連接 MYSQL 時(shí)的寫(xiě)法一樣。

這里有個(gè)需要注意的點(diǎn),ClickHouse 有個(gè) Array 類型,可以用來(lái)存數(shù)組,就像 ES 一樣。問(wèn)題是類型轉(zhuǎn)換需要自己定義。網(wǎng)上一些資料僅列出了基本類型的場(chǎng)景,我自己實(shí)現(xiàn)了一個(gè)轉(zhuǎn)換器,可以參考一下:

/** * Java Int 數(shù)組與 ClockHouse Array Int 轉(zhuǎn)換器 * @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 也給一個(gè)示例:

<?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 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 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 resultMap='BaseResultMap'> select <include refid='Base_Column_List' /> from user where id = #{id} limit 1 </select> <select resultMap='BaseResultMap' > select <include refid='Base_Column_List' /> from user </select></mapper>

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

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

以上就是如何將Mybatis連接到ClickHouse的詳細(xì)內(nèi)容,更多關(guān)于Mybatis連接到ClickHouse的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
99精品99| 亚洲乱亚洲高清| 蜜桃成人av| 日韩精品乱码av一区二区| 久久精品国产免费| 在线日韩av| 蜜桃久久久久| 日本中文字幕一区二区视频| 国产精品原创| 一本综合精品| 成人精品视频| 国产精品主播在线观看| 水蜜桃久久夜色精品一区的特点| 日产精品一区| 精品视频国内| 国产精品欧美一区二区三区不卡| 亚洲香蕉久久| 老司机精品久久| 国户精品久久久久久久久久久不卡| 国产精品久久久久久久久久久久久久久 | 91久久亚洲| 欧美一区久久久| 日韩a一区二区| 精品久久久网| 国产欧美大片| 国产精品久久久亚洲一区| 日韩激情一区二区| 男人的天堂亚洲一区| 1024精品久久久久久久久| 日韩在线第七页| 国产夫妻在线| 国产精品调教| 久久激五月天综合精品| 日本国产一区| 日本一区二区中文字幕| 亚洲人成网77777色在线播放 | 美女视频黄久久| 国产精品亚洲欧美日韩一区在线| 亚洲网站视频| 91成人网在线观看| 亚洲激精日韩激精欧美精品| 欧美色图一区| 在线一区免费| 蜜桃视频第一区免费观看| 亚洲一级高清| 国产综合亚洲精品一区二| 久久精品亚洲欧美日韩精品中文字幕| 精品一区二区三区中文字幕在线| 国产激情综合| 国内一区二区三区| 国际精品欧美精品| 天堂а√在线最新版中文在线| av高清不卡| 久久国产小视频| 91高清一区| 首页亚洲欧美制服丝腿| 亚洲精品影视| 国产精品久久久久av蜜臀| 久久精品二区亚洲w码| 国产精一区二区| 荡女精品导航| 亚洲高清毛片| 亚洲精选久久| 国产精品v亚洲精品v日韩精品| 精品一区二区男人吃奶 | 亚洲欧美日韩精品一区二区| 午夜亚洲福利| 国产激情一区| 精品成人免费一区二区在线播放| 久久国产直播| 鲁大师影院一区二区三区| 欧美日韩国产在线一区| 亚洲色图国产| 欧美aⅴ一区二区三区视频| 一区二区三区四区日本视频| 1024精品久久久久久久久| 四虎成人精品一区二区免费网站 | 免费日韩av片| 国产精品99精品一区二区三区∴| 久久精品国产精品亚洲毛片| 99久久精品网站| 一区二区三区四区日韩| 国产精品亚洲人成在99www| 欧美三级网址| 群体交乱之放荡娇妻一区二区| 欧美日韩国产传媒| 日本亚洲最大的色成网站www| 国产精品一区二区免费福利视频 | av中文字幕在线观看第一页 | 色综合视频一区二区三区日韩| 麻豆国产精品777777在线| 久久影视一区| 人人爱人人干婷婷丁香亚洲| 国产精品乱战久久久| 伊人久久在线| 日韩精品一级中文字幕精品视频免费观看 | 亚洲激情社区| 亚洲www免费| 精品入口麻豆88视频| 中文一区一区三区免费在线观| 久久激情一区| 五月天av在线| 国产精品99视频| 美日韩一区二区三区| 国产日韩欧美一区二区三区| 四虎精品永久免费| 亚洲精品在线国产| 视频在线在亚洲| 私拍精品福利视频在线一区| 国产高清亚洲| 久久精品超碰| 深夜福利亚洲| 日韩在线观看一区二区| 99国产精品视频免费观看一公开 | 久久爱www成人| 夜久久久久久| 亚洲精品成人| 久久精品国产精品亚洲毛片| 精品免费av| 国产亚洲精品美女久久 | 青青草伊人久久| 国产日韩欧美三区| 精品国产一级| 国产高清日韩| 精品丝袜在线| 亚洲永久字幕| 国产丝袜一区| 88久久精品| 国产在线观看www| 亚洲欧美日韩综合国产aⅴ| 一区免费视频| 国产亚洲观看| 日韩啪啪电影网| 亚洲一二av| 亚洲免费专区| 精品国产乱码| 日本不良网站在线观看| 欧美激情aⅴ一区二区三区| 综合国产视频| 国产一区二区三区黄网站| 91精品国产成人观看| 亚洲青青久久| 亚洲97av| а√天堂8资源在线| 亚洲色图综合| 亚洲无线一线二线三线区别av| 日韩一区二区三免费高清在线观看| 久久精品国产福利| 久久国产福利| 亚洲精品日韩久久| 丰满少妇一区| 亚洲欧洲一区二区天堂久久| 日韩av专区| 丝袜美腿一区| 日韩国产精品久久久久久亚洲| 伊人网在线播放| 精品一区二区三区中文字幕| 久久久久97| 性色一区二区| 首页国产精品| 午夜免费一区| 久久亚洲人体| 亚洲人成网77777色在线播放| 亚洲欧美日韩国产| 爽好久久久欧美精品| 免费福利视频一区二区三区| 麻豆亚洲精品| 亚洲精品女人| 青青草91久久久久久久久| 91精品啪在线观看国产18| 国产精品videosex极品| 在线人成日本视频| 国产欧美亚洲精品a| 蜜臀久久99精品久久一区二区| 深夜福利一区| 精品视频一区二区三区四区五区 | 成人精品亚洲| 亚洲一区黄色| 亚洲欧美一级| 综合激情网站| 超碰在线99| 国产剧情在线观看一区| 国产精品白丝av嫩草影院| 久久精品影视| 中文在线а√天堂| 久久在线91| 亚洲综合丁香| 激情视频一区二区三区| 久久夜夜操妹子| 亚洲三级毛片| 爽好多水快深点欧美视频| 免费不卡在线观看| 久久精品一区二区不卡| 国产视频一区二区在线播放| 亚洲欧洲另类| 欧美日韩一区二区三区视频播放| 国产一区二区三区亚洲综合| 国产日韩欧美三区| 日韩中文字幕一区二区三区| 精品视频一二|