Java (Spring AI) 实现MCP server实现数据库的智能问答
文章目录
一、前言
本文将详细介绍如何使用Java技术栈搭建MCP(Message Control Protocol)服务,实现高效的数据库问答功能。通过整合多种现代Java技术,我们可以构建一个稳定、高效且易于维护的数据库交互服务。
MCP 简介
Model Control Protocol (MCP) 是一种标准化协议,旨在通过结构化方式实现 AI 模型与外部工具及资源的交互。其核心特点包括:
- 跨平台兼容性:支持多种传输机制(如 HTTP、gRPC 等),适配不同部署环境。
- 模块化设计:提供标准化接口,便于集成第三方工具(如数据库、API 等)。
- 上下文管理:支持动态调整模型行为,例如实时更新输入输出规范。
MCP 的核心遵循客户端-服务器架构,其中主机应用程序可以连接到多个服务器:
官网地址:https://modelcontextprotocol.io/introduction
MCP Java SDK
MCP Java SDK为MCP提供 Java SDK 集成的项目。 该 SDK 使 Java 应用程序能够通过标准化接口与 AI 模型和工具进行交互,支持同步和异步通信模式。
-
客户端/服务器层:McpClient 处理客户端作,而 McpServer 管理服务器端协议作。两者都使用 McpSession 进行通信管理。
-
会话层 (McpSession):通过 DefaultMcpSession 实现管理通信模式和状态。
-
传输层 (McpTransport):处理 JSON-RPC 消息序列化和反序列化,并支持多种传输实现。
MCP 客户端是模型上下文协议 (MCP) 架构中的关键组件,负责建立和管理与 MCP 服务器的连接。它实现协议的客户端,处理:
-
协议版本协商,确保与服务器兼容
-
用于确定可用功能的功能协商
-
消息传输和 JSON-RPC 通信
-
工具发现和执行
-
资源访问和管理
-
提示系统交互
-
可选功能:
-
根管理
-
采样支持
-
-
同步和异步 API 支持
-
传输方式:
-
基于 Stdio 的传输,用于基于进程的通信
-
基于 Java HttpClient 的 SSE 客户端传输
-
用于反应式 HTTP 流的 WebFlux SSE 客户端传输

-
MCP 服务器
MCP 服务器是模型上下文协议 (MCP) 架构中的一个基础组件,它为客户端提供工具、资源和功能。它实现协议的服务器端,负责:
-
服务器端协议作实现
-
工具暴露和发现
-
使用基于 URI 的访问进行资源管理
-
提示模板提供和处理
-
与客户进行能力谈判
-
结构化日志记录和通知
-
-
并发客户端连接管理
-
同步和异步 API 支持
-
传输实现:
-
基于 Stdio 的传输,用于基于进程的通信
-
基于 Servlet 的 SSE 服务器传输
-
用于响应式 HTTP 流的 WebFlux SSE 服务器传输

-
官方文档地址:https://modelcontextprotocol.io/sdk/java/mcp-overview
项目地址:https://github.com/modelcontextprotocol/java-sdk
Spring AI MCP
Spring AI MCP 通过 Spring Boot 集成扩展了 MCP Java SDK,同时提供了客户端和服务器启动器
-
spring-ai-starter-mcp-client- 提供基于 STDIO 和 HTTP 的 SSE 支持的核心启动器
-
spring-ai-starter-mcp-client-webflux- 基于 WebFlux 的 SSE 传输实现
-
spring-ai-starter-mcp-server- 支持 STDIO 传输的核心服务器
-
spring-ai-starter-mcp-server-webmvc- 基于 Spring MVC 的 SSE 传输实现
-
spring-ai-starter-mcp-server-webflux- 基于 WebFlux 的 SSE 传输实现
这三种 Spring AI MCP 服务端的区别主要体现在传输协议和底层技术栈上,具体差异如下:
- 传输协议与通信模式
| 模块名称 | 传输协议 | 通信模式 | 适用场景 |
|---|---|---|---|
spring-ai-starter-mcp-server |
STDIO | 标准输入输出(进程间通信) | 本地进程内通信、命令行工具集成 |
spring-ai-starter-mcp-server-webmvc |
SSE (Server-Sent Events) | 基于 HTTP 的单向数据流(长连接) | 浏览器实时推送、REST API 风格服务 |
spring-ai-starter-mcp-server-webflux |
SSE (Server-Sent Events) | 基于 Reactive 的异步非阻塞长连接 | 高并发实时数据流场景 |
- 底层技术栈
- spring-ai-starter-mcp-server:
- 基于 标准输入输出(STDIO) 实现进程间通信。
- 通过 Java 的 ProcessBuilder 或类似机制与外部进程交互。
- 不依赖 Web 服务器,适用于本地环境或非 HTTP 场景。
- spring-ai-starter-mcp-server-webmvc:
- 基于 Spring MVC(Servlet API)实现。
- 使用传统的 Servlet 容器(如 Tomcat、Jetty)。
- 同步阻塞模型,适合传统 Web 应用和 REST API。
- spring-ai-starter-mcp-server-webflux:
- 基于 Spring WebFlux(Reactive API)实现。
- 使用异步非阻塞服务器(如 Netty、Reactor Netty)。
- 支持背压(Backpressure)和响应式编程模型,适合高并发场景。
- 性能与扩展性
| 特性 | STDIO 模式 | WebMVC (SSE) | WebFlux (SSE) |
|---|---|---|---|
| 线程模型 | 独立进程,不占用 Web 服务器线程 | 同步阻塞,依赖 Servlet 线程池 | 异步非阻塞,少量线程处理大量请求 |
| 并发能力 | 取决于进程资源 | 受限于 Servlet 容器线程数 | 支持数万并发连接(非阻塞) |
| 扩展性 | 需手动管理进程间通信 | 适合中小规模应用 | 适合高并发、微服务架构 |
- 使用场景
- 选择 STDIO 模式(spring-ai-starter-mcp-server):
- 需要与本地命令行工具或外部进程交互。
- 非 Web 环境,如批处理任务、本地脚本集成。
- 不需要 HTTP 接口,纯内部进程通信。
- 选择 WebMVC (SSE) 模式(spring-ai-starter-mcp-server-webmvc):
- 基于 REST API 的服务,需兼容传统 Web 框架。
- 同步处理逻辑,代码风格更接近传统 Spring 应用。
- 浏览器端实时数据推送(如实时日志、进度更新)。
- 选择 WebFlux (SSE) 模式(spring-ai-starter-mcp-server-webflux):
- 高并发场景,如实时数据分析、IoT 数据流处理。
- 微服务架构,需要非阻塞、低延迟的服务间通信。
- 响应式编程模型,与其他 Reactive 组件集成(如 Reactor、R2DBC)。
二、功能实现
1.项目创建
环境要求:
- Java 17
- Maven 3.6+
- Spring 3.4.5

pom.xml文件注意我们这里是mcp-server不要引入spring-boot-starter-web依赖
我这里使用的是spring-ai-starter-mcp-server-webflux
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.5</version>
<relativePath />
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>cn.codemaven</groupId>
<artifactId>mcp-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mcp-demo</name>
<description>mcp-demo</description>
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>3.4.5</spring-boot.version>
</properties>
<dependencies>
<!-- spring mcp依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
<!-- 数据库依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>central-portal-snapshots</id>
<name>Central Portal Snapshots</name>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>cn.codemaven.mcpdemo.McpDemoApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2.数据准备
准备mysql数据库测试数据
CREATE TABLE `user` (
`user_id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '用户名',
`password` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '密码',
`salt` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '盐',
`email` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '邮箱',
`mobile` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '手机号',
`status` tinyint DEFAULT NULL COMMENT '状态 0:禁用 1:正常',
`dept_id` bigint DEFAULT NULL COMMENT '部门ID',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`user_id`) USING BTREE,
UNIQUE KEY `username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1413 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC COMMENT='系统用户';
INSERT INTO `mcp_demo`.`user` (`user_id`, `username`, `password`, `salt`, `email`, `mobile`, `status`, `dept_id`, `create_time`) VALUES (413, '方致远', 'wEVqBtSQFw', 'nE26sUQzRF', 'zhiyuanf@hotmail.com', 'ApepUFQ0mk', 78, 569, '2003-10-02 05:05:50');
INSERT INTO `mcp_demo`.`user` (`user_id`, `username`, `password`, `salt`, `email`, `mobile`, `status`, `dept_id`, `create_time`) VALUES (414, '钱睿', 'Oh5OB6s5kj', 'v3C1K3wdNP', 'rqi2011@gmail.com', 'ePri67B4DK', 124, 504, '2002-12-24 22:57:04');
INSERT INTO `mcp_demo`.`user` (`user_id`, `username`, `password`, `salt`, `email`, `mobile`, `status`, `dept_id`, `create_time`) VALUES (415, '贺岚', 'IqHu95fhzU', '1IBSFZlPJF', 'hel@gmail.com', 'SdcE55O8g6', 61, 432, '2011-12-09 09:49:29');
INSERT INTO `mcp_demo`.`user` (`user_id`, `username`, `password`, `salt`, `email`, `mobile`, `status`, `dept_id`, `create_time`) VALUES (416, '姜詩涵', '9cmQsSZ0DL', 'N4vo2vMxcQ', 'jishiha@hotmail.com', 'dJk5TAgtmS', 69, 732, '2020-12-17 20:24:47');
INSERT INTO `mcp_demo`.`user` (`user_id`, `username`, `password`, `salt`, `email`, `mobile`, `status`, `dept_id`, `create_time`) VALUES (417, '周睿', '6uZ8yNwM9x', 'Mb7VAw4wZ6', 'rui1@icloud.com', 'bQzlM9TCHb', 107, 203, '2012-10-20 11:43:23');
INSERT INTO `mcp_demo`.`user` (`user_id`, `username`, `password`, `salt`, `email`, `mobile`, `status`, `dept_id`, `create_time`) VALUES (418, '丁璐', 'xrhQVMcpq8', 'HPbwTilYFf', 'ding97@icloud.com', '3hCdPTpPUo', 67, 446, '2024-01-25 14:05:59');
INSERT INTO `mcp_demo`.`user` (`user_id`, `username`, `password`, `salt`, `email`, `mobile`, `status`, `dept_id`, `create_time`) VALUES (419, '顾嘉伦', 'svo7RhePE5', 'rLwbs8yqUk', 'gujialun@hotmail.com', 'JOeQOWOXcI', 27, 611, '2008-11-30 15:13:50');
3.搭建用户查询的MCP Server服务
UserService用户服务
package cn.codemaven.mcpdemo.service;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
/**
* 用户服务
* @author :lzy
* @date :2025/7/22 20:22
*/
@Service
public class UserService {
@Value("${spring.datasource.url}")
private String dbUrl;
@Value("${spring.datasource.username}")
private String dbUsername;
@Value("${spring.datasource.password}")
private String dbPassword;
// 静态代码块,在类加载时注册数据库驱动
static {
try {
// 注册 MySQL 驱动
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
// 可根据实际情况替换为日志记录
throw new RuntimeException("数据库驱动加载失败:", e);
}
}
@Tool(name = "queryUserInfo", description = "根据id查询用户信息")
public Map queryUserInfo(@ToolParam( description = "用户id") String id) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
Map<String, String> resultMap = new HashMap<>();
try {
// 获取数据库连接
connection = DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
// 创建SQL语句
String sql = "SELECT * FROM user where user_id = ?";
statement = connection.prepareStatement(sql);
statement.setString(1, id);
// 执行SQL语句
resultSet = statement.executeQuery();
// 处理结果
ResultSetMetaData metaData = resultSet.getMetaData();
// 获取列的数量
int count = metaData.getColumnCount();
while(resultSet.next()){
for (int i = 1; i <= count; i++) {
String key = metaData.getColumnLabel(i);
String value = resultSet.getObject(i).toString();
resultMap.put(key, value);
}
}
return resultMap;
} catch (Exception e) {
e.printStackTrace();
} finally {
// 释放资源
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
ToolConfig注册工具
package cn.codemaven.mcpdemo.config;
import cn.codemaven.mcpdemo.service.UserService;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 注册工具
* @author :lzy
* @date :2025/7/22 20:33
*/
@Configuration
public class ToolConfig {
/**
* 注册用户服务
* @param userService
* @return
*/
@Bean
public ToolCallbackProvider userTools(UserService userService) {
return MethodToolCallbackProvider.builder().toolObjects(userService).build();
}
}
application.yml
# 端口
server:
port: 8080
spring:
ai:
mcp:
server:
name: db-mcp-server # 用于标识的服务器名称
sse-message-endpoint: /mcp/message #客户端用于发送消息的 Web 传输的自定义 SSE 消息终结点路径
version: 1.0.0 #服务器版本
type: SYNC # 服务器类型 (SYNC/ASYNC) 同步/异步
instructions: "该服务器提供用户信息工具和资源" # 可选说明,用于向客户端提供有关如何与此服务器交互的指导
sse-endpoint: /sse #用于 Web 传输的自定义 SSE 终结点路径
capabilities:
tool: true #启用/禁用工具功能
resource: true #启用/禁用资源功能
prompt: true #启用/禁用提示功能
completion: true #启用/禁用完成功能
#mysql配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mcp_demo?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
username: root
password: root
最终项目目录
搭建好服务后,启动McpDemoApplication,后台打印出下面的日志即表示配置成功

4.使用Cherry Studio测试
Cherry Studio官网下载地址: https://www.cherry-ai.com/
不会了解的可以参考我的另一篇博客https://superlu.blog.csdn.net/article/details/149534384
在Cherry Studio中配置mcp
点击添加服务器-》快速创建-》类型选择sse-》填写url为:http://localhost:8080/sse -》点击保存

切换到工具标签,可以看到 MCP 服务提供的工具信息
然后创建一个聊天助手并配置MCP服务
发送提问:“查询用户id为414的用户的信息”。大模型解析出请求参数id为414,然后向 MCP 服务发送请求,请求成功后返回数据库查询出的用户信息,然后根据用户信息作答.
5.实现数据库智能问答助手
总体思路如下 :
- 获取数据库全部库表结构给到大模型
- 创建sql执行工具
数据库元数据服务DatabaseMetadataService
package cn.codemaven.mcpdemo.service;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.sql.*;
/**
* 数据库元数据服务
* @author :lzy
* @date :2025/7/22 21:30
*/
@Service
public class DatabaseMetadataService {
@Value("${spring.datasource.url}")
private String dbUrl;
@Value("${spring.datasource.username}")
private String dbUsername;
@Value("${spring.datasource.password}")
private String dbPassword;
// 静态代码块,在类加载时注册数据库驱动
static {
try {
// 注册 MySQL 驱动
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
// 可根据实际情况替换为日志记录
throw new RuntimeException("数据库驱动加载失败:", e);
}
}
/**
* 获取MCP全部库表结构
* @return
*/
@Tool(name = "queryDatabaseMetadata", description = "获取MCP全部库表结构")
public String queryDatabaseMetadata() {
try {
return generateMarkdownReport();
} catch (SQLException e) {
// 可根据实际情况替换为日志记录
throw new RuntimeException("数据库元数据查询失败:", e);
}
}
/**
* 执行SQL语句
* @param sql
* @return
*/
@Tool(name = "executeSql", description = "执行SQL语句")
public String executeSql(String sql) {
try (Connection connection = DriverManager.getConnection(dbUrl, dbUsername, dbPassword)) {
try (Statement statement = connection.createStatement()) {
boolean hasResult = statement.execute(sql);
// 判断 SQL 语句类型
String lowerCaseSql = sql.trim().toLowerCase();
if (lowerCaseSql.startsWith("select")) {
// 处理查询语句
return handleQuery(statement, hasResult);
} else if (lowerCaseSql.startsWith("insert") || lowerCaseSql.startsWith("update") || lowerCaseSql.startsWith("delete")) {
// 处理增删改语句
int rowsAffected = statement.getUpdateCount();
return String.format("操作成功,影响了 %d 行记录。", rowsAffected);
} else {
return "不支持的 SQL 语句类型。";
}
}
} catch (SQLException e) {
throw new RuntimeException("SQL 执行失败:", e);
}
}
/**
* 处理查询语句
* @param statement
* @param hasResult
* @return
* @throws SQLException
*/
private String handleQuery(Statement statement, boolean hasResult) throws SQLException {
StringBuilder result = new StringBuilder();
do {
if (hasResult) {
try (ResultSet resultSet = statement.getResultSet()) {
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
// 构建表头,使用列注释
result.append("| ");
for (int i = 1; i <= columnCount; i++) {
String columnLabel = metaData.getColumnLabel(i);
result.append(columnLabel).append(" | ");
}
result.append("\n| ");
for (int i = 1; i <= columnCount; i++) {
result.append("---- | ");
}
result.append("\n");
// 构建表格内容
while (resultSet.next()) {
result.append("| ");
for (int i = 1; i <= columnCount; i++) {
Object value = resultSet.getObject(i);
result.append(value == null ? "null" : value.toString()).append(" | ");
}
result.append("\n");
}
}
}
hasResult = statement.getMoreResults();
} while (hasResult || statement.getUpdateCount() != -1);
return result.toString();
}
/**
* 生成Markdown格式的数据库元数据报告
* @return 格式化的Markdown报告
* @throws SQLException 如果数据库访问出错
*/
/**
* 生成Markdown格式的数据库元数据报告
* @return 格式化的Markdown报告
* @throws SQLException 如果数据库访问出错
*/
private String generateMarkdownReport() throws SQLException {
StringBuilder markdownReport = new StringBuilder();
markdownReport.append("# 数据库元数据报告\n\n");
try (Connection connection = DriverManager.getConnection(dbUrl, dbUsername, dbPassword)) {
// 获取当前连接的数据库名称
String catalog = connection.getCatalog();
// 获取数据库产品名称和版本
DatabaseMetaData dbMeta = connection.getMetaData();
markdownReport.append("## 数据库信息\n")
.append("- 数据库产品: ").append(dbMeta.getDatabaseProductName()).append("\n")
.append("- 版本: ").append(dbMeta.getDatabaseProductVersion()).append("\n")
.append("- 当前数据库: ").append(catalog).append("\n\n");
// 获取当前数据库的所有表
try (ResultSet tables = dbMeta.getTables(catalog, null, "%", new String[]{"TABLE", "VIEW"})) {
while (tables.next()) {
String tableName = tables.getString("TABLE_NAME");
String tableType = tables.getString("TABLE_TYPE");
String remarks = tables.getString("REMARKS");
markdownReport.append("## ").append(tableType).append(": ").append(tableName).append("\n");
if (remarks != null && !remarks.isEmpty()) {
markdownReport.append("> ").append(remarks).append("\n");
}
// 表结构
markdownReport.append("### 列结构\n");
markdownReport.append("| 列名 | 类型 | 大小 | 可空 | 默认值 | 注释 |\n");
markdownReport.append("|------|------|------|------|--------|------|\n");
try (ResultSet columns = dbMeta.getColumns(catalog, null, tableName, null)) {
while (columns.next()) {
String columnName = columns.getString("COLUMN_NAME");
String typeName = columns.getString("TYPE_NAME");
int columnSize = columns.getInt("COLUMN_SIZE");
String isNullable = columns.getString("IS_NULLABLE");
String columnDef = columns.getString("COLUMN_DEF");
String columnComment = columns.getString("REMARKS");
markdownReport.append("| ")
.append(columnName).append(" | ")
.append(typeName).append(" | ")
.append(columnSize).append(" | ")
.append(isNullable).append(" | ")
.append(columnDef != null ? columnDef : "NULL").append(" | ")
.append(columnComment != null ? columnComment : "").append(" |\n");
}
}
// 主键信息
markdownReport.append("\n### 主键\n");
markdownReport.append("| 列名 | 序列 |\n");
markdownReport.append("|------|------|\n");
try (ResultSet primaryKeys = dbMeta.getPrimaryKeys(catalog, null, tableName)) {
while (primaryKeys.next()) {
markdownReport.append("| ")
.append(primaryKeys.getString("COLUMN_NAME")).append(" | ")
.append(primaryKeys.getShort("KEY_SEQ")).append(" |\n");
}
}
// 外键信息
markdownReport.append("\n### 外键\n");
markdownReport.append("| 列名 | 引用表 | 引用列 |\n");
markdownReport.append("|------|--------|--------|\n");
try (ResultSet foreignKeys = dbMeta.getImportedKeys(catalog, null, tableName)) {
while (foreignKeys.next()) {
markdownReport.append("| ")
.append(foreignKeys.getString("FKCOLUMN_NAME")).append(" | ")
.append(foreignKeys.getString("PKTABLE_NAME")).append(" | ")
.append(foreignKeys.getString("PKCOLUMN_NAME")).append(" |\n");
}
}
markdownReport.append("\n");
}
}
}
return markdownReport.toString();
}
}
修改ToolConfig 注入DatabaseMetadataService
/**
* 注册数据库元数据服务
* @param databaseMetadataService
* @return
*/
@Bean
public ToolCallbackProvider databaseMetadataTools(DatabaseMetadataService databaseMetadataService) {
return MethodToolCallbackProvider.builder().toolObjects(databaseMetadataService).build();
}
使用Cherry Studio测试
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)