引言
DS V4实战篇:
DeepSeek V4 + Spring Boot 3 + JDK 21 :万字实战教你打造AI智能编码助手
DeepSeek V4 实战:打造一个智能 Java 项目源码分析助手
在上一篇文章中,我们利用 DeepSeek V4 的百万上下文能力构建了项目源码分析助手。本文将实验另一个高频场景:自然语言转 SQL。
业务人员写复杂 SQL 困难,开发人员手写的 SQL 可能索引缺失、全表扫描、性能低下。如果有一个工具,你只需要输入中文需求:"查询近 30 天每个品类的销售额排行,排除退货订单",它就能自动生成 SQL,并基于数据库真实执行计划给出优化建议和索引 DDL,这样是不是就很爽了!
本文将从零到一打造这样一个 SQL 智能生成与优化引擎,技术栈依然是前两章用到的 Java 21 + Spring Boot 3 ,核心 AI 能力由 DeepSeek V4 提供。前端提供一个简洁的 H5 页面,你输入需求,选择数据库方言,一键生成 SQL 并自动分析执行计划。
一、项目功能与架构
1.1 核心功能
| 模块 | 功能描述 |
|---|---|
| 自然语言 → SQL | 输入中文需求,DeepSeek V4 生成对应方言的 SQL |
| SQL 执行与 EXPLAIN | 通过 JDBC 执行 SQL 并获取执行计划 |
| 性能分析 | 将 EXPLAIN 结果送回 V4,识别索引缺失、全表扫描等问题 |
| 优化建议 | 输出优化后的 SQL + 索引创建 DDL |
| 数据库元数据感知 | 读取表结构、现有索引,辅助 V4 生成更精准的建议 |

1.2 技术栈
| 组件 | 版本 | 用途 |
|---|---|---|
| JDK | 21 | 虚拟线程、文本块 |
| Spring Boot | 3.5.14 | Web 框架 |
| DeepSeek V4 | deepseek-v4-pro/flash | SQL 生成与优化 |
| MySQL | 8.0+ | 测试数据库 |
1.3 项目结构
deepseek-sql-optimizer/
├── pom.xml
├── src/main/java/io/github/iweidujiang/dsv4/sqloptimizer/
│ ├── SqlOptimizerApplication.java
│ ├── config/
│ │ ├── DeepSeekConfig.java
│ ├── controller/
│ │ └── SqlController.java
│ ├── service/
│ │ ├── SqlGenerateService.java
│ │ └── DatabaseMetadataService.java
│ ├── dto/
│ │ ├── SqlRequest.java
│ │ └── SqlResponse.java
│ └── util/
│ └── JdbcExecutor.java
├── src/main/resources/
│ ├── application.yml
│ ├── static/
│ │ └── index.html
│ └── db/
│ └── schema.sql
二、数据库准备
为了演示,我们来创建一个电商风格的数据库:品类表 和 订单表。
2.1 表结构 SQL(MySQL)
sql
-- 创建数据库
CREATE DATABASE IF NOT EXISTS `demo-sql` DEFAULT CHARACTER SET utf8mb4;
USE `demo-sql`;
-- 品类表
CREATE TABLE `category` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL COMMENT '品类名称',
`parent_id` INT DEFAULT 0 COMMENT '父品类ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 订单表
CREATE TABLE `orders` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`order_no` VARCHAR(32) NOT NULL COMMENT '订单号',
`category_id` INT NOT NULL COMMENT '品类ID',
`amount` DECIMAL(10,2) NOT NULL COMMENT '订单金额',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '0-正常 1-退货',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_category` (`category_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.2 初始化数据
sql
-- 品类数据
INSERT INTO `category` (`name`) VALUES ('电子产品'), ('服装'), ('家电'), ('图书');
-- 订单数据(过去30天随机生成,这里给一些示例)
INSERT INTO `orders` (`order_no`, `category_id`, `amount`, `status`, `create_time`) VALUES
('O001', 1, 299.00, 0, DATE_SUB(NOW(), INTERVAL 5 DAY)),
('O002', 1, 459.00, 0, DATE_SUB(NOW(), INTERVAL 12 DAY)),
('O003', 2, 129.00, 1, DATE_SUB(NOW(), INTERVAL 3 DAY)), -- 退货
('O004', 2, 399.00, 0, DATE_SUB(NOW(), INTERVAL 20 DAY)),
('O005', 3, 1999.00, 0, DATE_SUB(NOW(), INTERVAL 8 DAY)),
('O006', 3, 799.00, 0, DATE_SUB(NOW(), INTERVAL 15 DAY)),
('O007', 4, 55.00, 0, DATE_SUB(NOW(), INTERVAL 2 DAY)),
('O008', 4, 89.00, 0, DATE_SUB(NOW(), INTERVAL 25 DAY)),
('O009', 1, 1299.00, 0, DATE_SUB(NOW(), INTERVAL 1 DAY)),
('O010', 2, 259.00, 0, DATE_SUB(NOW(), INTERVAL 18 DAY));
数据量较小,足够演示。实际使用时可以自行扩充。
三、核心技术实现
3.1 让 DeepSeek 理解你的数据库
模型本身不知道你的业务库长什么样,所以我们需要在提示词中动态注入数据库元数据。元数据包括:所有表名、每张表的列名和类型、已有的索引信息。
核心服务 DatabaseMetadataService 利用 JDBC 的 SHOW TABLES、SHOW COLUMNS、SHOW INDEX 将这些信息拼接成文本。
java
/**
* 获取数据库中所有表名、列信息、现有索引,用于增强提示词
*/
public String getSchemaContext() {
StringBuilder sb = new StringBuilder();
try {
// 获取所有表
List<String> tables = jdbcTemplate.queryForList(
"SHOW TABLES", String.class);
for (String table : tables) {
sb.append("表 ").append(table).append(":\n");
// 列信息
List<Map<String, Object>> columns = jdbcTemplate.queryForList(
"SHOW COLUMNS FROM " + table);
for (Map<String, Object> col : columns) {
sb.append(" 列: ").append(col.get("Field")).append(" 类型: ").append(col.get("Type"))
.append(" 是否可空: ").append(col.get("Null")).append("\n");
}
// 现有索引
List<Map<String, Object>> indexes = jdbcTemplate.queryForList(
"SHOW INDEX FROM " + table);
if (!indexes.isEmpty()) {
sb.append(" 已有索引: ");
String idxStr = indexes.stream()
.map(idx -> idx.get("Key_name").toString())
.distinct()
.collect(Collectors.joining(", "));
sb.append(idxStr).append("\n");
}
}
} catch (Exception e) {
log.warn("获取元数据失败", e);
return "无法获取数据库结构";
}
return sb.toString();
}
这样发送给 V4 的提示词就变成了:
数据库结构如下:
表 category:
列: id 类型: int 是否可空: NO
列: name 类型: varchar(50) ...
已有索引: PRIMARY
表 orders:
列: id ... 列: category_id ... 列: amount ...
已有索引: PRIMARY, idx_category, idx_create_time
用户需求:查询近30天每个品类的销售额排行,排除退货订单
数据库方言:mysql
请生成 SQL。
这种 "结构即上下文" 的方式,让 V4 生成的 SQL 能够准确匹配真实列名,而且能感知到现有索引,从而避免生成无法利用索引的 SQL。
3.2 生成 SQL:调用 V4 Pro 模型
提示词设计是重中之重。代码中设置对模型有两点硬性要求:
- 只输出 JSON,不要附带任何解释;
- 必须严格遵循指定的方言。
使用的 System Prompt 如下:
java
private static final String GENERATE_SQL_SYSTEM = """
你是一个资深 SQL 专家。根据用户的中文需求,生成符合指定方言的 SQL 查询语句。
输出格式必须是 JSON:{"sql": "生成的SQL语句"}
只输出 JSON,不要包含其他说明。
""";
用户提示则包含了前面拼接的元数据、用户需求和方言。调用 V4 Pro 后,解析 JSON 得到 SQL。
由于代码中使用了 Spring AI 的 ChatClient,只需几行就能完成调用。
具体实现见 https://github.com/iweidujiang/deepseek-v4-playground 的
SqlGenerateService.java。
3.3 执行 EXPLAIN:获取真实执行计划
生成的 SQL 是否正确?性能如何?不能只靠模型猜测。
可通过 JdbcExecutor 直接执行 EXPLAIN + 生成的 SQL,将数据库的真实执行计划捕获下来。
例如 MySQL 返回的一行可能是:
{id=1, select_type=SIMPLE, table=orders, type=ALL, possible_keys=idx_category, key=null, rows=10000, Extra=Using where}
type=ALL 意味着全表扫描,key=null 表示没有使用索引------这些都是优化的明确信号。
3.4 优化分析:交给 V4 Flash 模型
把原始需求、生成的 SQL 以及 EXPLAIN 结果三者打包,再次请求 DeepSeek,这次使用更便宜的 Flash 模型(成本只有 Pro 的 1/12 左右)。
System Prompt 要求输出 JSON:
json
{
"optimizedSql": "优化后的SQL语句",
"indexDdl": "CREATE INDEX ...",
"advice": "具体的优化建议文本"
}
V4 Flash 会根据执行计划中的 Extra 信息(如 Using filesort)和 key 为空等特征,推断出需要创建什么索引,有时还会改写成更高效的 SQL 写法(比如将 IN 改为 EXISTS)。
3.5 前端页面:一个 H5 就够了
所有功能通过一个单页的 index.html 暴露,放在 src/main/resources/static/ 下。
用户输入需求,点击按钮,后端返回三个部分:生成的 SQL、EXPLAIN 结果、优化建议和索引 DDL。页面样式简洁,启动 Spring Boot 后直接访问 http://localhost:8080 即可。
四、运行效果演示
启动项目后,访问:

输入中文需求,比如输入:查询近30天每个品类的销售额排行,选择 pro 模型,选择 MySQL,启用优化分析,点击生成 SQL:

可以看到:
- DeepSeek 理解了我们输入的中文语言并生成了 sql 语句
- 并且让它执行了 MySQL Explain 并输出了解析结果
- 通过解析结果给出了优化建议
五、总结
本文利用 DeepSeek V4 的推理能力,构建了一个 "自然语言 → SQL → 执行计划 → 优化建议" 的自动化工具。核心优势:
- 元数据驱动:让 AI "理解"你的数据库结构,减少幻觉。
- 闭环验证:基于真实 EXPLAIN,而不是理论分析。
- 成本可控:生成用 Pro 保证质量,优化用 Flash 降低成本。
- 开箱即用:H5 页面 + Spring Boot,一键启动。
DeepSeek V4 的 SQL 能力正在推动一种新的开发体验:从"写 SQL"到"描述业务",AI 负责翻译和打磨。
项目源码仓库 :https://github.com/iweidujiang/deepseek-v4-playground ,欢迎广大 coder 关注,star,感谢!