
springboot集成duckdb
DuckDB 是一个开源的 嵌入式分析型数据库管理系统(DBMS),设计用于高效地执行 OLAP(联机分析处理) 查询。它的目标是像 SQLite 一样易于嵌入,但专注于分析型工作负载,而不是事务型(OLTP)工作负载。
✅ DuckDB 的核心特点:
特性 | 描述 |
---|---|
嵌入式 | 无需服务器,直接嵌入到应用中(类似 SQLite)。 |
列式存储 | 数据按列存储,适合分析型查询。 |
SQL 支持 | 支持标准 SQL,包括窗口函数、CTE、JOIN、子查询等。 |
零依赖 | 单文件 C++ 库,易于集成。 |
高性能 | 向量化执行引擎,适合大数据量聚合、扫描、过滤等操作。 |
跨平台 | 支持 Linux、macOS、Windows。 |
多语言绑定 | 支持 Python、R、Java、Node.js、C++ 等。 |
✅springboot集成duckdb示例:
1.增加引用
<!-- DuckDB JDBC --> <!-- <dependency>--> <!-- <groupId>org.duckdb</groupId>--> <!-- <artifactId>duckdb_jdbc</artifactId>--> <!-- <version>1.3.2.1</version>--> <!-- </dependency>-->
2. 增加配置
datasource: dynamic: primary: master #设置默认的数据源或者数据源组,默认值即为master strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源 datasource: master: url: jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/${MYSQL_DATABASE}?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true username: ${MYSQL_USERNAME} password: ${MYSQL_PASSWORD} driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource # duck: # url: 'jdbc:duckdb::memory:' # 内存模式,重启丢;可改为 jdbc:duckdb:/data/ana.duckdb # driver-class-name: org.duckdb.DuckDBDriver # type: com.zaxxer.hikari.HikariDataSource # 用 Hikari 没问题 # # 下面 3 项必须填,否则 DS 启动校验失败 # username: sa # password: ''
3.初始化数据
package com.artefact.framework.handlers; import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; import jakarta.annotation.Resource; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.List; @Component @Log4j2 public class DuckdbLoadRunner implements CommandLineRunner { @Resource private DataSource dataSource; // @Value("${MYSQL_HOST}") private String MYSQL_HOST; @Value("${MYSQL_PORT}") private String MYSQL_PORT; @Value("${MYSQL_DATABASE}") private String MYSQL_DATABASE; @Value("${MYSQL_USERNAME}") private String MYSQL_USERNAME; @Value("${MYSQL_PASSWORD}") private String MYSQL_PASSWORD; @Override public void run(String... args) throws Exception { DataSource duckDs = ((DynamicRoutingDataSource) dataSource).getDataSource("duck"); DataSource mysqlDs = ((DynamicRoutingDataSource) dataSource).getDataSource("master"); try (Connection duck = duckDs.getConnection(); Connection mysql = mysqlDs.getConnection()) { try (Statement stmt = duck.createStatement()) { // 1. 加载扩展 stmt.execute("INSTALL mysql;"); stmt.execute("LOAD mysql;"); // 2. 建立 MySQL 连接串(与 yml 里保持一致) String mysqlConn = String.format("host=%s port=%s user=%s password=%s database=%s", MYSQL_HOST, MYSQL_PORT, MYSQL_USERNAME, MYSQL_PASSWORD, MYSQL_DATABASE); // 先 ATTACH(只需一次) String attachSql = "ATTACH '" + mysqlConn + "' AS mydb (TYPE mysql);"; stmt.execute(attachSql); // 3. 需要分析的表 List<String> tables = List.of("product", "style", "style_option", "sku"); for (String t : tables) { long start = System.currentTimeMillis(); duck.createStatement().execute( "CREATE OR REPLACE TABLE " + t + " AS SELECT * FROM mydb." + t); log.info("表 {} 导入完成,耗时 {} ms", t, System.currentTimeMillis() - start); } log.info("===== DuckDB 全量镜像完毕 ====="); } catch (SQLException e) { log.error("DuckDB 导入失败", e); } } catch (Exception e) { log.error("DuckDB 导入失败", e); } } }
4.duckdb sql注意事项(语法 和MYSQL不一样,坑很多)
例如:
SELECT COUNT(DISTINCT a.style_code) AS ofStyle FROM style_option a LEFT JOIN style s ON a.style_code = s.style_code CROSS JOIN json_each(a.colour_family) AS cfj(val) WHERE cfj.val IN ('"Black"') LIMIT 10 OFFSET 10;
注意事项:
1.CROSS JOIN
2.json_each
3. json_each展开后,字符串默认加了“XXX”,所以直接用In/=匹配XXX是无法匹配上的,必须要用“XXX”,如:WHERE cfj.val IN ('"Black"')
更多坑。。。
============ 欢迎各位老板打赏~ ===========


与本文相关的文章
- · MYSQL AES解密
- · docker定时任务Mysql脚本
- · docker安装mysql8注意事项
- · .NET8 Mysql SSL error
- · 定时备份docker中的mysql
- · springboot使用lock4j实现并发控制
- · springboot全局增加sentinel
- · Springboot整合Swagger常用注解
- · swagger隐藏authentication参数
- · Spring Security 中的自定义PreAuthorize 注解
- · docker-compose通过容器名连接mysql
- · JACKSON和FASTJSON处理返回JSON数据中为NULL字段不显示