当前位置: 首页 > news >正文

Java (Spring AI) 实现MCP server实现数据库的智能问答

文章目录

  • 一、前言
    • MCP 简介
    • MCP Java SDK
    • Spring AI MCP
  • 二、功能实现
    • 1.项目创建
    • 2.数据准备
    • 3.搭建用户查询的MCP Server服务
    • 4.使用Cherry Studio测试
    • 5.实现数据库智能问答助手


一、前言

本文将详细介绍如何使用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) 架构中的关键组件,负责建立和管理与 MCP 服务器的连接。它实现协议的客户端,处理:

  • 协议版本协商,确保与服务器兼容

  • 用于确定可用功能的功能协商

  • 消息传输和 JSON-RPC 通信

  • 工具发现和执行

  • 资源访问和管理

  • 提示系统交互

  • 可选功能:

    • 根管理

    • 采样支持

  • 同步和异步作

  • 交通方式:

    • 基于 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 传输实现

Standard MCP Server、WebMVC Server Transport 和 WebFlux Server Transport 是三种不同的服务器实现方式,主要用于支持模型上下文协议(MCP)的通信。

  1. Standard MCP Server
  • 核心功能:Standard MCP Server 是基于标准输入/输出(STDIO)的服务器实现。它主要用于进程内通信,适合在同一个进程中运行客户端和服务器端,通过标准输入输出流进行数据交互。
  • 适用场景:适用于简单的本地开发环境或单进程应用,不涉及复杂的网络通信。
  • 特点:实现简单,但不具备网络通信能力,无法支持分布式或多进程环境。
  1. WebMVC Server Transport
  • 核心功能:WebMVC Server Transport 是基于 Spring MVC 的服务器实现。它通过 Servlet 提供服务器发送事件(SSE)支持,允许服务器主动向客户端推送数据。
  • 适用场景:适合传统的基于 Servlet 的 Web 应用程序,能够与现有的 Spring MVC 项目无缝集成。
  • 特点:
    • 基于 Servlet API,支持阻塞式 I/O 操作。
    • 提供标准化的 SSE 端点(如 /mcp/sse),客户端可以通过 text/event-stream 协议与服务器通信。
    • 支持同步模式,适合传统的请求-响应模式。
  1. WebFlux Server Transport
  • 核心功能:WebFlux Server Transport 是基于 Spring WebFlux 的服务器实现。它提供了响应式 SSE 支持,能够处理高并发的异步流式数据。
  • 适用场景:适合需要高性能、非阻塞 I/O 的现代响应式应用,特别是在处理大量并发连接时表现出色。
  • 特点:
    • 基于响应式编程模型,支持非阻塞操作。
    • 提供响应式的 SSE 端点,客户端可以通过 text/event-stream 协议与服务器进行流式交互。
    • 支持异步模式,适合需要高并发和低延迟的应用。

总结

  • Standard MCP Server 适合简单的本地开发和单进程通信。
  • WebMVC Server Transport 适合传统的基于 Servlet 的 Web 应用,支持同步模式。
  • WebFlux Server Transport 适合高性能、高并发的响应式应用,支持异步模式。

二、功能实现

1.项目创建

环境要求:

  • Java 17
  • Maven 3.6+
  • Spring 3.4.5
    在这里插入图片描述

pom.xml文件
注意我们这里是mcp-server不要引入spring-boot-starter-web依赖

<?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服务

参考源码
https://github.com/spring-projects/spring-ai-examples/tree/main/model-context-protocol/weather/starter-stdio-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*/@Beanpublic 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.Driverurl: jdbc:mysql://localhost:3306/mcp_demo?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTCusername: rootpassword: 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.实现数据库智能问答助手

总体思路如下 :

  1. 获取数据库全部库表结构给到大模型
  2. 创建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*/@Beanpublic ToolCallbackProvider databaseMetadataTools(DatabaseMetadataService databaseMetadataService) {return  MethodToolCallbackProvider.builder().toolObjects(databaseMetadataService).build();}

使用Cherry Studio测试
在这里插入图片描述

http://www.dtcms.com/a/292634.html

相关文章:

  • SpringAOP的实现原理和场景
  • 《汇编语言:基于X86处理器》第9章 字符串和数组(2)
  • 服务器租用:网络钓鱼具体是指什么?
  • Linux 内核与底层开发
  • Linux 下分卷压缩与解压缩全指南:ZIP 与 TAR.GZ 实战
  • Python趣味算法:实现任意进制转换算法原理+源码
  • Spring Boot环境搭建与核心原理深度解析
  • 【Dij】P1807 最长路
  • Linux文件——文件系统Ext2(1)_理解硬件
  • js的基本内容:引用、变量、打印、交互、定时器、demo操作
  • 【LeetCode 热题 100】46. 全排列——回溯
  • Windows 编程辅助技能:转到文档
  • 【方案】网页由微应用拼图,微前端
  • 『 C++ 入门到放弃 』- 红黑树
  • 一文详解Java类中的构造器是什么及主要特性
  • 70.爬楼梯
  • ABP VNext 报表:EPPlus DinkToPdf 多格式导出
  • redis秒杀之lua脚本
  • 20250722解决在Ubuntu 24.04.2下编译RD-RK3588开发板的Android13出现找不到python2的问题
  • GraphRAG的部署和生成检索过程体验
  • C++11--锁分析
  • npm全局安装后,依然不是内部或外部命令,也不是可运行的程序或批处理文件
  • 大数据量查询计算引发数据库CPU告警问题复盘
  • 使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第二十二讲)
  • Linux_Ext系列文件系统基本认识(一)
  • Product Hunt 每日热榜 | 2025-07-22
  • “鱼书”深度学习入门 笔记(1)前四章内容
  • day19 链表
  • 【科研绘图系列】R语言绘制柱状堆积图
  • 基于 Vue,SPringBoot开发的新能源充电桩的系统