DuckDB + Spring Boot + MyBatis 构建高性能本地数据分析引擎

news2025/6/8 16:09:49

DuckDB 是一款令人兴奋的内嵌式分析型数据库 (OLAP),它为本地数据分析和处理带来了前所未有的便捷与高效 🚀。它无需外部服务器,可以直接在应用程序进程中运行,并提供了强大的 SQL 支持和列式存储带来的高性能。


什么是 DuckDB? 🦆

DuckDB 被誉为“数据科学领域的 SQLite”,是一个开源的、专为分析查询设计的嵌入式数据库管理系统。它与传统的行式数据库(如 SQLite,主要用于事务处理 OLTP)不同,DuckDB 采用列式存储向量化查询执行引擎,这使得它在处理聚合、扫描和复杂分析查询时速度极快。

核心特性:

  • • 内嵌式 (In-Process): 无需单独的服务器进程,直接作为库链接到宿主应用程序中。

  • • 分析型 (OLAP): 专为分析查询优化,而非高并发事务处理。

  • • SQL 友好: 提供丰富且标准的 SQL 接口,支持复杂查询、窗口函数等。

  • • 列式存储: 数据按列存储,分析查询通常只涉及部分列,大大减少 I/O。

  • • 向量化执行: CPU 一次处理一批数据(向量),而不是一条一条处理,效率更高。

  • • 快速数据导入/导出: 能高效读写常见数据格式,如 CSV, Parquet, JSON。

  • • 事务支持 (ACID): 保证数据操作的原子性、一致性、隔离性和持久性。

  • • 易于安装和使用: 通常是一个单一的文件或库,依赖少。

  • • 丰富的 API: 提供 C/C++, Python, Java (JDBC), R, Node.js, Go, Rust 等语言的接口。


为什么要选择 DuckDB?

在以下场景中,DuckDB 表现出色:

  • • 本地数据分析与探索: 直接在本地机器上对 CSV, Parquet 等文件进行快速 SQL 查询和分析,无需导入到大型数据库。

  • • 嵌入式分析: 将分析能力直接嵌入到应用程序中,例如在 Web 应用中提供报表或数据可视化功能。

  • • ETL 替代方案: 对于中小型数据集,可以用 DuckDB 替代复杂的 ETL 工具,进行数据转换和清洗。

  • • 教学与原型验证: 学习 SQL 和数据库概念的绝佳工具,也适合快速验证数据处理逻辑。

  • • 交互式数据应用: 例如,构建一个允许用户通过 SQL 查询本地数据集的桌面应用。


Spring Boot + MyBatis 集成 DuckDB 教程 ☕

将 DuckDB 与流行的 Java Web 框架 Spring Boot 和持久层框架 MyBatis 集成起来非常简单,可以让你在 Java 应用中方便地利用 DuckDB 的强大功能。

1. 添加依赖 (Maven)

在你的 pom.xml 文件中添加以下依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jdbc</artifactId>
    </dependency>

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>3.0.3</version> </dependency>

    <dependency>
        <groupId>org.duckdb</groupId>
        <artifactId>duckdb_jdbc</artifactId>
        <version>0.10.2</version> </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

注意:请务必检查 DuckDB JDBC 驱动和 MyBatis Spring Boot Starter 的最新版本。

2. 配置数据源

在 src/main/resources/application.properties (或 .yml) 文件中配置数据源:

# DuckDB DataSource Configuration
# 使用文件持久化:
spring.datasource.url=jdbc:duckdb:mydatabase.duckdb
# 或者使用内存模式 (每次重启数据丢失):
# spring.datasource.url=jdbc:duckdb:
spring.datasource.driver-class-name=org.duckdb.DuckDBDriver
# DuckDB 本地文件或内存模式通常不需要用户名和密码
# spring.datasource.username=
# spring.datasource.password=

# MyBatis Configuration
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.configuration.map-underscore-to-camel-case=true
  • • jdbc:duckdb:mydatabase.duckdb 会在项目根目录下(或指定路径)创建/使用一个名为 mydatabase.duckdb 的数据库文件。

  • • jdbc:duckdb: (或 jdbc:duckdb::memory:) 会使用纯内存数据库,速度最快,但数据不会持久化。

3. 创建实体类 (可选,但推荐)

package com.example.duckdbdemo.model;

public class Product {
    private Integer id;
    private String name;
    private Double price;

    // Getters and Setters
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public Double getPrice() { return price; }
    public void setPrice(Double price) { this.price = price; }

    @Override
    public String toString() {
        return "Product{" +
               "id=" + id +
               ", name='" + name + '\'' +
               ", price=" + price +
               '}';
    }
}

4. 创建 MyBatis Mapper 接口

package com.example.duckdbdemo.mapper;

import com.example.duckdbdemo.model.Product;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface ProductMapper {

    @Update("CREATE TABLE IF NOT EXISTS products (id INTEGER PRIMARY KEY, name VARCHAR, price DECIMAL(10, 2))")
    void createTable();

    @Insert("INSERT INTO products (id, name, price) VALUES (#{id}, #{name}, #{price})")
    void insert(Product product);

    @Select("SELECT id, name, price FROM products WHERE id = #{id}")
    Product findById(Integer id);

    @Select("SELECT id, name, price FROM products")
    List<Product> findAll();

    @Select("SELECT COUNT(*) FROM products")
    int count();
}
  • • @Mapper 注解使其能被 Spring Boot 自动扫描到。

  • • 我们在这里添加了一个 createTable 方法,用于在应用启动时(如果表不存在)创建表。

5. 创建服务和示例用法

package com.example.duckdbdemo.service;

import com.example.duckdbdemo.mapper.ProductMapper;
import com.example.duckdbdemo.model.Product;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ProductService {

    private static final Logger log = LoggerFactory.getLogger(ProductService.class);

    private final ProductMapper productMapper;

    @Autowired
    public ProductService(ProductMapper productMapper) {
        this.productMapper = productMapper;
    }

    @PostConstruct // 在依赖注入完成后执行
    public void init() {
        log.info("Initializing ProductService...");
        productMapper.createTable(); // 创建表(如果不存在)
        log.info("Products table checked/created.");

        if (productMapper.count() == 0) {
            log.info("No products found, inserting sample data...");
            Product p1 = new Product();
            p1.setId(1);
            p1.setName("DuckDB Super Book");
            p1.setPrice(29.99);
            productMapper.insert(p1);

            Product p2 = new Product();
            p2.setId(2);
            p2.setName("Quacky IDE Extension");
            p2.setPrice(15.50);
            productMapper.insert(p2);
            log.info("Sample data inserted.");
        }
    }

    public Product getProductById(Integer id) {
        return productMapper.findById(id);
    }

    public List<Product> getAllProducts() {
        return productMapper.findAll();
    }
}

6. 运行和测试

创建一个 Spring Boot 主应用类:

package com.example.duckdbdemo;

import com.example.duckdbdemo.model.Product;
import com.example.duckdbdemo.service.ProductService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DuckdbDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DuckdbDemoApplication.class, args);
    }

    @Bean
    CommandLineRunner runner(ProductService productService) {
        return args -> {
            System.out.println("Fetching product with ID 1:");
            Product product1 = productService.getProductById(1);
            System.out.println(product1);

            System.out.println("\nFetching all products:");
            productService.getAllProducts().forEach(System.out::println);
        };
    }
}

运行 DuckdbDemoApplication,你将在控制台看到 DuckDB 被初始化,表被创建,数据被插入和查询的结果。


DuckDB 使用注意事项

  • • 并发性: DuckDB 对于单个持久化数据库文件是单写入者/多读取者模型。这意味着多个连接可以同时读取数据,但只有一个连接可以在特定时间点写入数据。对于内存数据库 (:memory:),每个连接默认获得一个独立的私有数据库。这使其非常适合分析查询和嵌入式场景,但不适合需要高并发写入的传统 OLTP 应用。

  • • 驱动版本: 确保 DuckDB JDBC 驱动版本与你的需求和 DuckDB 的特性兼容。

  • • 内存使用: 虽然 DuckDB 很高效,但复杂的分析查询仍然可能消耗大量内存,尤其是在处理大数据集时。

  • • 文件路径: 当使用文件持久化的 DuckDB 时,确保 JDBC URL 中的路径对于应用程序是可写可读的。


总结 🌟

DuckDB 以其高性能、易用性和内嵌式的特点,为数据分析领域带来了新的活力。通过与 Spring Boot 和 MyBatis 的简单集成,Java 开发者可以轻松地将 DuckDB 的强大分析能力引入到自己的应用程序中,无论是用于本地数据处理、嵌入式分析报表,还是快速原型开发,DuckDB 都是一个值得尝试的优秀工具。它使得在应用程序中直接运行复杂的 SQL 分析查询变得前所未有地简单和高效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2404297.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是预训练?深入解读大模型AI的“高考集训”

1. 预训练的通俗理解&#xff1a;AI的“高考集训” 我们可以将预训练&#xff08;Pre-training&#xff09; 形象地理解为大模型AI的“高考集训”。就像学霸在高考前需要刷五年高考三年模拟一样&#xff0c;大模型在正式诞生前&#xff0c;也要经历一场声势浩大的“题海战术”…

鸿蒙仓颉语言开发实战教程:购物车页面

大家上午好&#xff0c;仓颉语言商城应用的开发进程已经过半&#xff0c;不知道大家通过这一系列的教程对仓颉开发是否有了进一步的了解。今天要分享的购物车页面&#xff1a; 看到这个页面&#xff0c;我们首先要对它简单的分析一下。这个页面一共分为三部分&#xff0c;分别是…

OPENCV的AT函数

一.AT函数介绍 在 OpenCV 中&#xff0c;at&#xff08;&#xff09; 是一个模板成员函数&#xff0c;用于访问和修改矩阵或图像中特定位置的元素。它提供了一种直接且类型安全的方式来操作单个像素值&#xff0c;但需要注意其性能和类型匹配问题 AT函数是OPENCV中重要的函数…

ISO 17387——解读自动驾驶相关标准法规(LCDAS)

Intelligent transport systems — Lane change decision aid systems (LCDAS) — Performance requirements and test procedures(First edition: 2008-05-01) 原文链接&#xff1a;https://cdn.standards.iteh.ai/samples/43654/701fd49bde7b4d3db165444b7c6f0c53/ISO-17387…

智慧零售管理中的客流统计与属性分析

智慧零售管理中的视觉分析技术应用 一、背景与需求 随着智慧零售的快速发展&#xff0c;传统零售门店面临管理效率低、安全风险高、客户体验差等问题。通过视觉分析技术&#xff0c;智慧零售管理系统可实现对门店内人员行为的实时监控与数据分析&#xff0c;从而提升运营效率…

Ps:Adobe PDF 预设

Ps菜单&#xff1a;编辑/Adobe PDF 预设 Edit/Adobe PDF Presets 通过“Adobe PDF 预设” Adobe PDF Presets对话框&#xff0c;可以查看 Adobe PDF 预设&#xff0c;了解复杂的 PDF 设置。还可以编辑、新建、删除、载入预设&#xff0c;根据最终用途&#xff08;如高质量打印、…

靶场(二十)---靶场体会小白心得 ---jacko

老样子开局先看端口&#xff0c;先看http端口 PORT STATE SERVICE VERSION 80/tcp open http Microsoft IIS httpd 10.0 |_http-title: H2 Database Engine (redirect) | http-methods: |_ Potentially risky methods: TRACE |_http-server-header:…

​​高频通信与航天电子的材料革命:猎板PCB高端压合基材技术解析​​

—聚酰亚胺/陶瓷基板在5G与航天场景的产业化应用​​ ​​一、极端环境材料体系&#xff1a;突破温域与频率极限​​ ​​聚酰亚胺基板&#xff08;PI&#xff09;的航天级稳定性​​ 猎板在卫星通信PCB中采用真空层压工艺处理聚酰亚胺基材&#xff08;Dk≈10.2&#xff09;&a…

WPF技术体系与现代化样式

目录 ​​1 WPF技术架构解析​​ ​​1.1 技术演进与定位​​ ​​1.2 核心机制对比​​ ​​2 样式与资源系统​​ ​​2.1 资源(Resource)定义与作用域​​ ​​2.2 样式(Style)与触发器​​ ​​3 开发环境配置(.NET 8)​​ ​​3.1 安装流程​​ ​​3.2 项目结…

【工具教程】PDF电子发票提取明细导出Excel表格,OFD电子发票行程单提取保存表格,具体操作流程

在企业财务管理领域&#xff0c;电子发票提取明细导出表格是不可或缺的工具。 月末财务结算时&#xff0c;财务人员需处理成百上千张电子发票&#xff0c;将发票明细导出为表格后&#xff0c;通过表格强大的数据处理功能&#xff0c;可自动分类汇总不同项目的支出金额&#xff…

基于STM32的DHT11温湿度远程监测LCD1602显示Proteus仿真+程序+设计报告+讲解视频

DHT11温湿度远程监测proteus仿真 1. 主要功能2.仿真3. 程序4. 设计报告5. 资料清单&下载链接 基于STM32的DHT11温湿度远程监测LCD1602显示Proteus仿真设计(仿真程序设计报告讲解视频&#xff09; 仿真图proteus 8.9 程序编译器&#xff1a;keil 5 编程语言&#xff1a;C…

分类预测 | Matlab实现CNN-BiLSTM-Attention高光谱数据分类预测

分类预测 | Matlab实现CNN-BiLSTM-Attention高光谱数据分类预测 目录 分类预测 | Matlab实现CNN-BiLSTM-Attention高光谱数据分类预测分类效果功能概述程序设计参考资料 分类效果 功能概述 该MATLAB代码实现了一个结合CNN、BiLSTM和注意力机制的高光谱数据分类预测模型&#x…

微软推出SQL Server 2025技术预览版,深化人工智能应用集成

在Build 2025 大会上&#xff0c;微软向开发者社区开放了SQL Server 2025的测试版本。该版本的技术改进主要涵盖人工智能功能集成、系统性能优化与开发工具链升级三个维度&#xff0c;展示了数据库管理系统在智能化演进方向上的重要进展。 智能数据处理功能更新 新版本的技术亮…

RocketMQ入门5.3.2版本(基于java、SpringBoot操作)

一、RocketMQ概述 RocketMQ是一款由阿里巴巴于2012年开源的分布式消息中间件&#xff0c;旨在提供高吞吐量、高可靠性的消息传递服务。主要特点有&#xff1a; 灵活的可扩展性 海量消息堆积能力 支持顺序消息 支持多种消息过滤方式 支持事务消息 支持回溯消费 支持延时消…

使用osqp求解简单二次规划问题

文章目录 一、问题描述二、数学推导1. 目标函数处理2. 约束条件处理 三、代码编写 一、问题描述 已知&#xff1a; m i n ( x 1 − 1 ) 2 ( x 2 − 2 ) 2 s . t . 0 ⩽ x 1 ⩽ 1.5 , 1 ⩽ x 2 ⩽ 2.5 min(x_1-1)^2(x_2-2)^2 \qquad s.t. \ \ 0 \leqslant x_1 \leqslant 1.5,…

【C语言】通用统计数据结构及其更新函数(最值、变化量、总和、平均数、方差等)

【C语言】通用统计数据结构及其更新函数&#xff08;最值、变化量、总和、平均数、方差等&#xff09; 更新以gitee为准&#xff1a; gitee 文章目录 通用统计数据结构更新函数附录&#xff1a;压缩字符串、大小端格式转换压缩字符串浮点数压缩Packed-ASCII字符串 大小端转换什…

Spring AI(10)——STUDIO传输的MCP服务端

Spring AI MCP&#xff08;模型上下文协议&#xff09;服务器Starters提供了在 Spring Boot 应用程序中设置 MCP 服务器的自动配置。它支持将 MCP 服务器功能与 Spring Boot 的自动配置系统无缝集成。 本文主要演示支持STDIO传输的MCP服务器 仅支持STDIO传输的MCP服务器 导入j…

Sklearn 机器学习 缺失值处理 填充数据列的缺失值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 💡使用 Scikit-learn 处理数据缺失值的完整指南 在机器学习项目中,数据缺失是不可避…

猜字符位置游戏-position gasses

import java.util.*;public class Main {/*字符猜位置游戏;每次提交只能被告知答对几个位置;根据提示答对的位置数推测出每个字符对应的正确位置;*/public static void main(String[] args) {char startChar A;int gameLength 8;List<String> ballList new ArrayList&…

宝塔安装配置FRP

FRP&#xff08;Fast Reverse Proxy&#xff09;作为一款高性能的反向代理应用&#xff0c;能够帮助我们轻松实现内网穿透&#xff0c;将内网服务暴露到公网&#xff0c;满足远程访问、开发调试等多种需求。宝塔面板以其简洁易用的界面和强大的功能&#xff0c;成为众多站长和开…