SpringAI 功能体验之SQL智能助手:用自然语言查询数据库
1. 引言
在之前的文章中,我们体验了SpringAI在RAG(检索增强生成)方面的强大能力,让AI能够基于本地知识库回答问题。今天,我们将继续探索SpringAI的另一个实用功能——SQL智能助手。
SQL智能助手的核心思想是:让用户通过自然语言描述查询需求,由AI自动生成对应的SQL语句,并执行查询返回结果。这对于不熟悉SQL语法的业务人员来说,可以极大降低数据查询的门槛;对于开发人员来说,也能快速生成复杂查询,提升工作效率。
本文将通过一个具体的案例,带大家一步步使用SpringAI构建一个SQL智能问答系统。
2. 功能概述
SpringAI的SQL智能助手功能,本质上是一个Text-to-SQL的解决方案。其工作流程如下:
- 用户输入自然语言问题:例如“查询上个月销售额最高的5个商品”。
- AI理解问题并生成SQL:SpringAI将用户的问题、数据库表结构信息(DDL)以及一些示例查询(可选)一起发送给大模型。
- 大模型返回SQL语句:大模型根据提供的上下文,生成对应的SQL查询语句。
- 执行SQL并返回结果:SpringAI执行生成的SQL语句,并将查询结果返回给用户。
SpringAI通过SqlService和相关的ChatClient配置,简化了这一流程,让我们可以专注于业务逻辑。
3. 环境准备
在开始之前,我们需要准备好以下环境:
- JDK 17+
- Spring Boot 3.x 项目
- SpringAI 依赖(当前版本 1.0.0-M6)
- 一个可用的数据库(本文以MySQL为例)
- AI大模型API(本文以OpenAI兼容接口为例)
3.1 创建Spring Boot项目并引入依赖
首先,创建一个Spring Boot项目,并在pom.xml中引入SpringAI的相关依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.5</version>
<relativePath/>
</parent>
<dependencies>
<!-- Spring AI Starter -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Spring JDBC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
3.2 配置文件
在application.yml中配置AI模型和数据库连接信息:
spring:
ai:
openai:
api-key: ${AI_API_KEY} # 你的API Key
base-url: ${AI_BASE_URL} # API地址,例如 https://api.openai.com
chat:
options:
model: gpt-4o-mini # 使用的模型
datasource:
url: jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC
username: root
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
4. 核心实现
4.1 定义数据库表结构
为了让AI能够理解我们的数据库,我们需要提供表结构信息。这里我们以一个简单的orders(订单表)和products(商品表)为例:
CREATE TABLE products (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
category VARCHAR(100),
price DECIMAL(10, 2),
stock INT
);
CREATE TABLE orders (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
product_id BIGINT,
quantity INT,
total_amount DECIMAL(10, 2),
order_date DATETIME,
FOREIGN KEY (product_id) REFERENCES products(id)
);
4.2 创建SQL助手服务
SpringAI提供了一个SqlService接口,我们可以通过ChatClient来构建它。核心思路是:在ChatClient的Prompt中,注入数据库的DDL(数据定义语言)和用户的问题。
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.model.ModelOptionsUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* Author: roy
* Description:SQL智能助手服务
*/
@Service
public class SqlAssistantService {
private final ChatClient chatClient;
private final JdbcTemplate jdbcTemplate;
@Value("classpath:sql-prompt-template.st")
private Resource sqlPromptResource;
public SqlAssistantService(ChatClient.Builder builder, JdbcTemplate jdbcTemplate) {
this.chatClient = builder.build();
this.jdbcTemplate = jdbcTemplate;
}
/**
* 根据自然语言问题生成并执行SQL
* @param question 用户的自然语言问题
* @return 查询结果
*/
public String askDatabase(String question) {
// 1. 获取数据库表结构信息(DDL)
String schema = getDatabaseSchema();
// 2. 构建Prompt,将DDL和用户问题传递给AI
PromptTemplate promptTemplate = new PromptTemplate(sqlPromptResource);
Prompt prompt = promptTemplate.create(Map.of(
"question", question,
"ddl", schema
));
// 3. 调用AI生成SQL
String sql = chatClient.prompt(prompt).call().content();
// 4. 清理并执行SQL
String cleanSql = cleanSql(sql);
try {
List<Map<String, Object>> results = jdbcTemplate.queryForList(cleanSql);
return ModelOptionsUtils.toJsonString(results);
} catch (Exception e) {
return "执行SQL时出错:" + e.getMessage() + ",生成的SQL为:" + cleanSql;
}
}
/**
* 获取数据库中所有表的DDL
*/
private String getDatabaseSchema() {
// 这里简化处理,实际项目中可以查询 information_schema 来动态获取
return """
CREATE TABLE products (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
category VARCHAR(100),
price DECIMAL(10, 2),
stock INT
);
CREATE TABLE orders (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
product_id BIGINT,
quantity INT,
total_amount DECIMAL(10, 2),
order_date DATETIME,
FOREIGN KEY (product_id) REFERENCES products(id)
);
""";
}
/**
* 清理AI返回的SQL,去除Markdown标记等
*/
private String cleanSql(String rawSql) {
return rawSql
.replace("```sql", "")
.replace("```", "")
.trim();
}
}
4.3 创建Prompt模板
在resources目录下创建sql-prompt-template.st文件,这是指导AI如何生成SQL的核心提示词:
你是一个SQL专家。请根据用户的问题和提供的数据库表结构(DDL),生成对应的SQL查询语句。
要求:
1. 只返回SQL语句,不要包含任何解释。
2. SQL语句必须是可执行的。
3. 如果问题不明确,请做出合理的假设。
数据库表结构(DDL):
{ddl}
用户问题:
{question}
请生成SQL:
4.4 创建Controller
最后,创建一个Controller来暴露API接口:
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Author: roy
* Description:SQL智能助手控制器
*/
@RestController
public class SqlAssistantController {
@Resource
private SqlAssistantService sqlAssistantService;
@GetMapping("/ask")
public String askDatabase(@RequestParam("question") String question) {
return sqlAssistantService.askDatabase(question);
}
}
5. 测试运行
启动项目后,我们可以通过以下URL进行测试:
- 查询所有商品:
http://localhost:8080/ask?question=查询所有商品 - 查询价格大于100的商品:
http://localhost:8080/ask?question=查询价格大于100的商品有哪些 - 查询订单总数:
http://localhost:8080/ask?question=统计一下总共有多少订单 - 查询每个分类的商品数量:
http://localhost:8080/ask?question=统计每个分类的商品数量
AI会根据你的问题,自动生成对应的SQL并执行,返回JSON格式的结果。
6. 进阶优化
6.1 动态获取表结构
上面的例子中,我们硬编码了DDL。在实际项目中,可以通过查询information_schema来动态获取所有表的DDL,这样当数据库结构发生变化时,无需修改代码。
6.2 增加Few-Shot示例
为了让AI生成更准确的SQL,可以在Prompt中提供一些“问题-SQL”的示例(Few-Shot),帮助AI理解你的数据模式和查询习惯。
6.3 安全性考虑
- 权限控制:用于执行SQL的数据库账号应仅具有只读权限,防止AI生成
DELETE、DROP等危险操作。 - SQL校验:在执行前,可以对生成的SQL进行正则校验,确保只包含
SELECT语句。 - 结果限制:在生成的SQL中自动添加
LIMIT子句,防止返回过多数据。
7. 总结
通过本文的实践,我们成功使用SpringAI构建了一个SQL智能助手。它能够将自然语言转换为SQL查询,并直接返回数据库中的结果。这大大降低了数据查询的门槛,让非技术人员也能轻松获取数据。
SpringAI的SQL助手功能,结合了LLM的自然语言理解能力和传统数据库的查询能力,是AI赋能企业数据应用的一个绝佳范例。未来,随着SpringAI的不断完善,我们期待它能提供更多开箱即用的企业级AI功能。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)