SpringAI SQL 智能助手实战:用自然语言查询数据库
·
1. 引言
在传统开发中,查询数据库通常需要编写 SQL 语句,这对非技术用户来说门槛较高。借助 SpringAI 框架,我们可以构建一个智能 SQL 助手,让用户通过自然语言直接查询数据库,大幅降低数据访问门槛。
本文将带你从零搭建一个基于 SpringAI 的 SQL 智能助手,实现「说人话,查数据」的效果。
2. 技术栈与前置准备
2.1 技术选型
| 组件 | 版本 | 说明 |
|---|---|---|
| Spring Boot | 3.2+ | 应用框架 |
| SpringAI | 1.0.0-M6+ | AI 集成框架 |
| JDK | 17+ | 运行环境 |
| MySQL / H2 | 任意 | 目标数据库 |
| OpenAI / 兼容 API | — | LLM 服务 |
2.2 核心依赖
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.0.0-M6</version>
</dependency>
3. 核心实现思路
整个流程分为三步:
- 获取数据库 Schema:读取表结构、字段、类型、注释等信息
- 构造 Prompt:将 Schema 与用户自然语言问题组装成结构化提示词
- 调用 LLM 生成 SQL:由 AI 模型返回对应的 SQL 查询语句
4. 代码实现
4.1 数据库 Schema 读取
@Component
public class SchemaReader {
@Resource
private JdbcTemplate jdbcTemplate;
public String getTableSchema(String tableName) {
String sql = """
SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ?
""";
List<Map<String, Object>> columns = jdbcTemplate.queryForList(sql, tableName);
StringBuilder sb = new StringBuilder();
sb.append("表名:").append(tableName).append("\n");
for (Map<String, Object> col : columns) {
sb.append("- ").append(col.get("COLUMN_NAME"))
.append(" (").append(col.get("DATA_TYPE")).append(")")
.append(":").append(col.get("COLUMN_COMMENT")).append("\n");
}
return sb.toString();
}
}
4.2 Prompt 模板设计
public class SqlPromptTemplate {
public static String build(String schema, String userQuestion) {
return """
你是一个 SQL 专家。根据以下数据库表结构,将用户的自然语言问题转换为 SQL 查询语句。
表结构:
%s
用户问题:%s
请只返回 SQL 语句,不要额外解释。
""".formatted(schema, userQuestion);
}
}
4.3 核心服务类
@Service
public class SqlAssistantService {
@Resource
private ChatClient chatClient;
@Resource
private SchemaReader schemaReader;
public String ask(String question, String tableName) {
String schema = schemaReader.getTableSchema(tableName);
String prompt = SqlPromptTemplate.build(schema, question);
return chatClient.prompt(prompt).call().content();
}
}
4.4 Controller 接口
@RestController
@RequestMapping("/api/sql-assistant")
public class SqlAssistantController {
@Resource
private SqlAssistantService sqlAssistantService;
@PostMapping("/ask")
public String ask(@RequestParam String question,
@RequestParam String tableName) {
return sqlAssistantService.ask(question, tableName);
}
}
5. 配置与运行
5.1 application.yml
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
base-url: https://api.openai.com
chat:
options:
model: gpt-4o-mini
datasource:
url: jdbc:mysql://localhost:3306/your_db
username: root
password: your_password
5.2 启动与测试
启动 Spring Boot 应用后,使用 curl 测试:
curl -X POST "http://localhost:8080/api/sql-assistant/ask" \
-d "question=查询最近7天的订单数量" \
-d "tableName=orders"
返回示例:
SELECT COUNT(*) AS order_count
FROM orders
WHERE order_date >= CURDATE() - INTERVAL 7 DAY;
6. 进阶优化
6.1 多表关联
对于涉及多表的查询,可以一次性传入多个表的 Schema:
public String getMultiTableSchema(List<String> tableNames) {
return tableNames.stream()
.map(this::getTableSchema)
.collect(Collectors.joining("\n---\n"));
}
6.2 安全校验
为防止 SQL 注入或危险操作,可以在执行前做校验:
public boolean isReadOnlyQuery(String sql) {
String trimmed = sql.trim().toUpperCase();
return trimmed.startsWith("SELECT") || trimmed.startsWith("WITH");
}
6.3 结果缓存
对相同问题可做缓存,减少 LLM 调用次数:
@Cacheable(value = "sqlCache", key = "#question + ':' + #tableName")
public String ask(String question, String tableName) {
// ...
}
7. 总结
本文通过 SpringAI 框架实现了一个 SQL 智能助手,核心思路是:读取 Schema → 构造 Prompt → 调用 LLM → 生成 SQL。你可以在此基础上扩展多表查询、安全校验、缓存优化等能力,打造一个生产级的自然语言查询工具。
下一步可以尝试:
- 接入更多数据库类型(PostgreSQL、Oracle 等)
- 支持 DDL 语句生成
- 集成前端对话界面
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)