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字段不显示
