Spring AI + 通义千问:实现自然语言查数据库

0 阅读5分钟

我用 Spring AI + 大模型做了个自然语言查数据库的工具,开源项目分享!

摘要:还在为写 SQL 头秃?试试用中文提问直接生成报表!本文分享一个基于 Spring AI 打造的智能数据洞察平台,支持 RAG 检索增强、MCP 协议集成,让数据分析像聊天一样简单。


一、效果展示:用中文提问,3 秒出报表

先上效果图!

项目界面预览 - 客户消费排行

图 1:输入"消费金额最多的前五个客户是谁",系统自动生成 SQL 并展示数据可视化

项目界面预览 - 商品利润分析

图 2:输入"哪五个商品利润最高",智能推荐柱状图展示

项目界面预览

图 3:项目主界面预览

是不是有点意思?继续往下看,我会带你深入了解这个项目的技术实现。


二、项目背景

作为一名后端开发,我经常需要帮运营、产品同事从数据库里查数据:

  • "上个月销售额多少?"
  • "哪个地区订单最多?"
  • "最近 7 天的用户增长趋势如何?"

这些问题看似简单,但每次都手动写 SQL 实在太低效了。于是我想:能不能用自然语言直接查数据库?

借助 Spring AI 和大模型的能力,我做了这个 InsightFlow 项目 —— 一个智能数据洞察平台。


三、核心功能

3.1 自然语言查询

用户只需用中文提问,系统自动理解意图并生成 SQL:

用户输入:上个月有多少订单?
生成 SQL: SELECT COUNT(*) FROM orders
         WHERE DATE_FORMAT(created_at, '%Y-%m') = DATE_FORMAT(NOW(), '%Y-%m')

3.2 智能可视化推荐

根据查询类型自动推荐图表:

问题类型推荐图表
趋势分析折线图
占比分布饼图
排名对比柱状图
明细数据表格

3.3 RAG 检索增强 + 自动同步

这是项目的一大亮点:RAG 知识库无需手动维护!

项目启动时会自动读取数据库所有表结构信息(表名、字段、注释等),生成 ops.txt 文档并存入向量数据库。这意味着:

  • 零维护成本:数据库变更无需手动更新文档
  • 实时同步:每次启动自动同步最新表结构
  • 准确率高:AI 始终基于最新的 schema 生成 SQL

💡 前提条件:需要平时规范维护数据库表注释和字段注释,这是 RAG 准确性的关键!

@Configuration
public class DatabaseDocAutoGenerateConfig {
    @Bean
    @Order(1)
    public CommandLineRunner generateDatabaseDocOnStartup(DatabaseDocService docService) {
        return args -> {
            // 应用启动时自动生成数据库文档
            docService.generateToOpsTxt();
        };
    }
}

3.4 MCP 协议集成

支持通过 Model Context Protocol 调用外部工具,扩展性更强。


四、技术架构

4.1 技术栈

├── 后端框架:Spring Boot 3.5.5
├── AI 框架:Spring AI 1.0.0 + Spring AI Alibaba
├── 大模型:通义千问 (DashScope)
├── 向量库:Redis Stack (Vector Search)
├── 数据库:MySQL 8.x
├── 前端:HTML5 + ECharts 5.4.3
└── JDK:Java 21

4.2 核心代码解析

(1)RAG 检索增强配置
@Configuration
public class SpringAIConfig {
    @Bean
    public TokenTextSplitter tokenTextSplitter() {
        // 文本分块配置:每块 500 tokens,最小 200 字符
        return new TokenTextSplitter(500, 200, 1, 10000, true);
    }
}
(2)报表生成服务核心逻辑
@Service
@Slf4j
public class ReportGenerationService {

    @Resource(name = "qwenChatClient")
    private ChatClient chatClient;

    @Resource
    private VectorStore vectorStore;

    private static final String SYSTEM_PROMPT = """
        你是一个专业的数据分析师和 SQL 专家。
        要求:
        1. 根据用户问题生成 SQL 查询
        2. 使用标准 MySQL 语法
        3. 时间查询使用 DATE_FORMAT 函数
        4. 只返回 SQL 语句,不要其他内容
        """;

    public ReportResult generateReport(String question) {
        // 1. 使用 RAG 增强的 AI 生成 SQL
        String sql = generateSqlFromNaturalLanguage(question);

        // 2. 安全校验:只允许 SELECT 语句
        if (!sql.trim().toUpperCase().startsWith("SELECT")) {
            throw new IllegalArgumentException("只支持 SELECT 查询");
        }

        // 3. 执行查询并返回结果
        List<Map<String, Object>> data = jdbcTemplate.queryForList(sql);
        return buildReportResult(question, sql, data);
    }

    private String generateSqlFromNaturalLanguage(String question) {
        RetrievalAugmentationAdvisor advisor = RetrievalAugmentationAdvisor.builder()
            .documentRetriever(VectorStoreDocumentRetriever.builder()
                .vectorStore(vectorStore).build())
            .build();

        return chatClient.prompt()
            .advisors(advisor)  // 使用 RAG 顾问
            .system(SYSTEM_PROMPT)
            .user(question)
            .call()
            .content();
    }
}

代码解读

  1. RAG 检索增强:通过 RetrievalAugmentationAdvisor 在生成 SQL 前,先从向量库中检索相关的表结构信息
  2. 安全防护:严格校验只允许 SELECT 语句,防止 SQL 注入
  3. 意图识别:通过 System Prompt 引导 AI 生成符合语法的 SQL
(3)可视化推荐算法
private String generateVisualizationSuggestion(String question, List<Map<String, Object>> data) {
    String q = question.toLowerCase();

    // 趋势类问题 - 折线图
    if (q.contains("趋势") || q.contains("变化") || q.contains("每月")) {
        return "折线图";
    }
    // 占比类问题 - 饼图
    if (q.contains("占比") || q.contains("比例")) {
        return "饼图";
    }
    // 对比类问题 - 柱状图
    if (q.contains("对比") || q.contains("排名") || q.contains("最高")) {
        return "柱状图";
    }
    // 默认表格
    return data.size() <= 10 ? "表格" : "表格";
}

五、快速体验

环境要求

软件版本要求用途
JDK21+Java 运行环境
Maven3.6+构建工具
MySQL8.x业务数据库
Redis6.2+ (推荐 Redis Stack)向量数据库

秘钥配置

配置项说明获取方式
aliQwen-api阿里云 DashScope API Keydashscope.console.aliyun.com/apiKey
spring.data.redis.passwordRedis 密码自建 Redis 或云服务商提供

启动步骤

1. 克隆项目
git clone https://github.com/snowandsky/insightflow.git
cd insightflow
2. 配置环境变量

Windows:

# 在系统环境变量中添加
set ALI_QWEN_API=你的 DashScope API Key

Linux/Mac:

export ALI_QWEN_API="你的 DashScope API Key"
3. 修改配置文件

编辑 InsightFlow-module/src/main/resources/application.properties

# Redis 配置
spring.data.redis.host=localhost
spring.data.redis.port=6379
spring.data.redis.password=你的密码

# MySQL 配置
spring.datasource.url=jdbc:mysql://localhost:3306/ecommerce?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=你的密码
4. 初始化数据库
# 登录 MySQL
mysql -u root -p

# 执行建表脚本
source InsightFlow-module/src/main/resources/01-schema.sql

# (可选) 执行测试数据
source InsightFlow-module/src/main/resources/02-data.sql
5. 构建并运行
# Maven 构建
mvn clean package -DskipTests

# 运行应用
mvn spring-boot:run -pl InsightFlow-module

# 或直接运行 JAR
java -jar InsightFlow-module/target/InsightFlow-module-0.0.1-SNAPSHOT.jar
6. 访问页面
http://localhost:8017/report

详细部署文档请参考:GitHub 仓库


六、总结与展望

InsightFlow 目前实现了:

  • ✅ 自然语言转 SQL 查询
  • ✅ RAG 检索增强 + 自动同步
  • ✅ 智能可视化推荐
  • ✅ MCP 协议集成
  • ✅ 数据库文档自动生成

后续计划:

  • 支持更多数据库(PostgreSQL、Oracle)
  • 增加导出 Excel/PDF 功能
  • 支持多轮对话式分析
  • 集成更多图表类型

七、求 Star 🌟

如果你觉得这个项目对你有帮助或启发,欢迎到 GitHub 点个 Star 支持一下!

👉 项目地址github.com/snowandsky/…

也欢迎关注我的掘金账号,后续会持续分享更多技术干货!


参考资源


文章结语:AI 时代,让数据说话不再困难。希望 InsightFlow 能给你一些启发,也欢迎提 Issue/PR 一起完善这个项目!