From 1de75e93de97c9966741b90a694f2ddb6f1f24bc Mon Sep 17 00:00:00 2001 From: "Mr.xiaoZH" <15202822317@163.com> Date: Fri, 25 Jul 2025 11:49:50 +0800 Subject: [PATCH] =?UTF-8?q?magic=E5=A2=9E=E5=8A=A0clickhouse=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E7=9A=84=E6=95=B0=E6=8D=AE=E6=BA=90=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../magic-api-plugin-clickhouse/pom.xml | 39 ++++++++++++ .../clickhouse/ClickHouseFunction.java | 42 +++++++++++++ .../magicapi/clickhouse/ClickHouseModule.java | 60 +++++++++++++++++++ .../clickhouse/ClickHouseProperties.java | 38 ++++++++++++ .../MagicClickHouseConfiguration.java | 34 +++++++++++ magic-api-plugins/pom.xml | 1 + .../modules/db/dialect/ClickhouseDialect.java | 26 +++++++- 7 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 magic-api-plugins/magic-api-plugin-clickhouse/pom.xml create mode 100644 magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/ClickHouseFunction.java create mode 100644 magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/ClickHouseModule.java create mode 100644 magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/ClickHouseProperties.java create mode 100644 magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/MagicClickHouseConfiguration.java diff --git a/magic-api-plugins/magic-api-plugin-clickhouse/pom.xml b/magic-api-plugins/magic-api-plugin-clickhouse/pom.xml new file mode 100644 index 00000000..87748149 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-clickhouse/pom.xml @@ -0,0 +1,39 @@ + + + + magic-api-plugins + org.ssssssss + 2.2.2 + + 4.0.0 + magic-api-plugin-clickhouse + magic-api-plugin-clickhouse + magic-api clickhouse plugin + + + + org.ssssssss + magic-api + + + com.clickhouse + clickhouse-jdbc + 0.4.6 + true + + + + org.lz4 + lz4-java + 1.8.0 + true + + + org.springframework.boot + spring-boot-autoconfigure + true + + + \ No newline at end of file diff --git a/magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/ClickHouseFunction.java b/magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/ClickHouseFunction.java new file mode 100644 index 00000000..a45406cc --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/ClickHouseFunction.java @@ -0,0 +1,42 @@ +package org.ssssssss.magicapi.clickhouse; + +import org.ssssssss.magicapi.core.config.MagicFunction; +import org.ssssssss.script.annotation.Comment; +import org.ssssssss.script.annotation.Function; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class ClickHouseFunction implements MagicFunction { + + @Function + @Comment("格式化ClickHouse日期时间") + public static String formatDateTime(Object dateTime, String pattern) { + if (dateTime instanceof LocalDateTime) { + return ((LocalDateTime) dateTime).format(DateTimeFormatter.ofPattern(pattern)); + } + return dateTime.toString(); + } + + @Function + @Comment("生成ClickHouse UUID") + public static String generateUUID() { + return java.util.UUID.randomUUID().toString(); + } + + @Function + @Comment("转换为ClickHouse数组格式") + public static String toArray(Object... values) { + StringBuilder sb = new StringBuilder("["); + for (int i = 0; i < values.length; i++) { + if (i > 0) sb.append(","); + if (values[i] instanceof String) { + sb.append("'").append(values[i]).append("'"); + } else { + sb.append(values[i]); + } + } + sb.append("]"); + return sb.toString(); + } +} \ No newline at end of file diff --git a/magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/ClickHouseModule.java b/magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/ClickHouseModule.java new file mode 100644 index 00000000..dccbc5a5 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/ClickHouseModule.java @@ -0,0 +1,60 @@ +package org.ssssssss.magicapi.clickhouse; + +import org.springframework.jdbc.core.JdbcTemplate; +import org.ssssssss.magicapi.core.annotation.MagicModule; +import org.ssssssss.script.annotation.Comment; + +import javax.sql.DataSource; +import java.util.List; +import java.util.Map; + +@MagicModule("clickhouse") +public class ClickHouseModule { + + private final JdbcTemplate jdbcTemplate; + + public ClickHouseModule(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @Comment("执行ClickHouse查询") + public List> query(String sql, Object... params) { + return jdbcTemplate.queryForList(sql, params); + } + + @Comment("执行ClickHouse插入") + public int insert(String sql, Object... params) { + return jdbcTemplate.update(sql, params); + } + + @Comment("执行ClickHouse更新") + public int update(String sql, Object... params) { + return jdbcTemplate.update(sql, params); + } + + @Comment("执行ClickHouse删除") + public int delete(String sql, Object... params) { + return jdbcTemplate.update(sql, params); + } + + @Comment("批量插入数据") + public int[] batchInsert(String sql, List batchArgs) { + return jdbcTemplate.batchUpdate(sql, batchArgs); + } + + @Comment("获取表结构信息") + public List> describeTable(String database, String table) { + String sql = "DESCRIBE TABLE " + database + "." + table; + return jdbcTemplate.queryForList(sql); + } + + @Comment("获取数据库列表") + public List showDatabases() { + return jdbcTemplate.queryForList("SHOW DATABASES", String.class); + } + + @Comment("获取表列表") + public List showTables(String database) { + return jdbcTemplate.queryForList("SHOW TABLES FROM " + database, String.class); + } +} \ No newline at end of file diff --git a/magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/ClickHouseProperties.java b/magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/ClickHouseProperties.java new file mode 100644 index 00000000..83482a61 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/ClickHouseProperties.java @@ -0,0 +1,38 @@ +package org.ssssssss.magicapi.clickhouse; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "magic-api.clickhouse") +public class ClickHouseProperties { + + private String url = "jdbc:ch://localhost:8123/default"; + private String username = "default"; + private String password = ""; + private String driverClassName = "com.clickhouse.jdbc.ClickHouseDriver"; + private int maxActive = 20; + private int initialSize = 1; + private int maxWait = 60000; + private int minIdle = 1; + private boolean testOnBorrow = false; + private boolean testOnReturn = false; + private boolean testWhileIdle = true; + private int validationQueryTimeout = 5000; + private int timeBetweenEvictionRunsMillis = 60000; + private int numTestsPerEvictionRun = 3; + private int minEvictableIdleTimeMillis = 300000; + + // getters and setters + public String getUrl() { return url; } + public void setUrl(String url) { this.url = url; } + + 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 getDriverClassName() { return driverClassName; } + public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; } + + // ... 其他getter/setter方法 +} \ No newline at end of file diff --git a/magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/MagicClickHouseConfiguration.java b/magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/MagicClickHouseConfiguration.java new file mode 100644 index 00000000..7a8cdef4 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-clickhouse/src/main/java/org/ssssssss/magicapi/clickhouse/MagicClickHouseConfiguration.java @@ -0,0 +1,34 @@ +package org.ssssssss.magicapi.clickhouse; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; +import org.ssssssss.magicapi.core.config.MagicPluginConfiguration; +import org.ssssssss.magicapi.core.model.Plugin; + +import javax.sql.DataSource; + +@Configuration +@ConditionalOnClass(name = "com.clickhouse.jdbc.ClickHouseDriver") +@EnableConfigurationProperties(ClickHouseProperties.class) +public class MagicClickHouseConfiguration implements MagicPluginConfiguration { + + @Override + public Plugin plugin() { + return new Plugin("ClickHouse"); + } + + @Bean + @ConditionalOnMissingBean + public ClickHouseModule clickHouseModule(DataSource dataSource) { + return new ClickHouseModule(new JdbcTemplate(dataSource)); + } + + @Bean + public ClickHouseFunction clickHouseFunction() { + return new ClickHouseFunction(); + } +} \ No newline at end of file diff --git a/magic-api-plugins/pom.xml b/magic-api-plugins/pom.xml index 8ea1dd66..7c104573 100644 --- a/magic-api-plugins/pom.xml +++ b/magic-api-plugins/pom.xml @@ -24,6 +24,7 @@ magic-api-plugin-cluster magic-api-plugin-git magic-api-plugin-nebula + magic-api-plugin-clickhouse diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/dialect/ClickhouseDialect.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/dialect/ClickhouseDialect.java index 284bc5b4..dd3e844a 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/dialect/ClickhouseDialect.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/dialect/ClickhouseDialect.java @@ -1,5 +1,9 @@ package org.ssssssss.magicapi.modules.db.dialect; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.ssssssss.magicapi.modules.db.BoundSql; + /** * ClickHouse方言 * @@ -7,8 +11,28 @@ package org.ssssssss.magicapi.modules.db.dialect; */ public class ClickhouseDialect extends MySQLDialect { + private static final Logger logger = LoggerFactory.getLogger(ClickhouseDialect.class); + @Override public boolean match(String jdbcUrl) { - return jdbcUrl.contains(":clickhouse:"); + boolean matches = jdbcUrl.contains(":clickhouse:") || jdbcUrl.contains(":ch:"); + if (matches) { + logger.info("ClickHouse方言匹配成功: {}", jdbcUrl); + } + return matches; + } + + @Override + public String getPageSql(String sql, BoundSql boundSql, long offset, long limit) { + logger.info("使用ClickHouse分页语法: LIMIT {} OFFSET {}", limit, offset); + boundSql.addParameter(limit); + boundSql.addParameter(offset); + return sql + " LIMIT ? OFFSET ?"; + } + + @Override + public String getCountSql(String sql) { + // ClickHouse的COUNT查询优化 + return "SELECT COUNT(*) FROM (" + sql + ") AS count_table"; } } -- Gitee