Spring-Ai-Mcp-Server 快速入门

  1. 添加依赖
xml 复制代码
<properties>
        <java.version>21</java.version>
        <spring-ai.version>1.0.1</spring-ai.version>
        <spring-boot.version>3.4.3</spring-boot.version>
    </properties>

   <dependencies>
       <dependency>
           <groupId>org.springframework.ai</groupId>
           <artifactId>spring-ai-starter-mcp-server</artifactId>
           <version>${spring-ai.version}</version>
       </dependency>
       <dependency>
           <groupId>org.springframework.ai</groupId>
           <artifactId>spring-ai-starter-model-deepseek</artifactId>
           <version>${spring-ai.version}</version>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-actuator</artifactId>
           <version>${spring-boot.version}</version>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
           <version>${spring-boot.version}</version>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-logging</artifactId>
           <version>${spring-boot.version}</version>
       </dependency>
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>8.0.33</version>
       </dependency>
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <version>1.18.36</version>
       </dependency>
   </dependencies>
  1. 编写tools
java 复制代码
@Slf4j
@Service
public class Nl2SqlTools {

    private static final String url = "jdbc:mysql://localhost:3306/";
    private static final String user = "root";
    private static final String password = "iwzf.88xa([";

    private static <T> T query(String sql, String db, RowMapper<T> mapper) {
        try (Connection connection = DriverManager.getConnection(url + db, user, password);
             Statement statement = connection.createStatement();
             ResultSet resultSet = statement.executeQuery(sql);) {
            log.info("query sql: {}", sql);
            return mapper.mapRow(resultSet);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Tool(description = "Get tables in a database")
    public List<String> getTables(String db) {
        log.info("getTables db: {}", db);
        String sql = "show tables";
        return query(sql, db, rs -> {
            List<String> tables = new ArrayList<>();
            while (rs.next()) {
                tables.add(rs.getString(1));
            }
            return tables;
        });
    }

    @Tool(description = "Get columns in a table")
    public List<Column> getColumns(String db, String table) {
        String sql = "SELECT column_name, data_type,  column_comment FROM information_schema.columns WHERE table_name ='%s'";
        log.info("getColumns db: {}, table: {}", db, table);
        return query(String.format(sql, table), db, rs -> {
            List<Column> columns = new ArrayList<>();
            while (rs.next()) {
                Column column = new Column();
                column.setName(rs.getString(1));
                column.setType(rs.getString(2));
                column.setComment(rs.getString(3));
                columns.add(column);
            }
            return columns;
        });
    }

    @Tool(description = "Get results of a SQL query")
    public List<Map<String, Object>> getResults(String db, String sql) {
        log.info("getResults db: {}, sql: {}", db, sql);
        return query(sql, db, rs -> {
            List<Map<String, Object>> results = new ArrayList<>();
            int columnCount = rs.getMetaData().getColumnCount();
            while (rs.next()) {
                Map<String, Object> row = new java.util.HashMap<>();
                for (int i = 1; i <= columnCount; i++) {
                    row.put(rs.getMetaData().getColumnName(i), rs.getObject(i));
                }
                results.add(row);
            }
            return results;
        });
    }


    @Getter
    @Setter
    public static class Column {
        private String name;
        private String type;
        private String comment;
    }


    public static interface RowMapper<T> {
        T mapRow(ResultSet rs) throws SQLException;
    }
}
  1. 编写用于测试的controller
java 复制代码
@RestController
public class Nl2SqlController {

    private final ChatClient client;


    public Nl2SqlController(ChatClient.Builder builder) {
        this.client = builder
                .build();
    }

    @GetMapping("/nl2sql")
    public String nl2sql(String nl) {
        return client.prompt("用户的自然语言问题: " + nl + ",请将用户的自然语言问题转换为SQL查询语句,SQL查询语句必须符合Doris语法规范,SQL查询语句只能返回SQL语句本身,不能包含任何多余的文字说明。" +
                        "1. SQL查询语句必须符合Doris语法规范。" +
                        "2. 从用户的提问中,提取到数据库名。" +
                        "3. 根据数据库名,先获取到所有表,用户选择表之后,再根据表名获取所有的字段信息。" +
                        "4. 然后根据字段信息,生成SQL查询语句。" +
                        "5. 生成的Sql, 在调用执行sql 的方法,获取数据。")
                .user(nl)
                .tools(new Nl2SqlTools())
                .call()
                .content();
    }
}
  1. 然后大家就可以启动整个spring boot项目,调用http://localhost:8080/nl2sql接口进行测试了
相关推荐
Moonbit3 小时前
MoonBit Pearls Vol.9:正则表达式引擎的两种实现方法:导数与 Thompson 虚拟机
后端·正则表达式·编程语言
文心快码BaiduComate3 小时前
一人即团队,SubAgent引爆开发者新范式
前端·后端·程序员
掘金一周3 小时前
2025年还有前端不会Nodejs ?| 掘金一周 9.25
android·前端·后端
RoyLin3 小时前
前端·后端·node.js
泉城老铁3 小时前
springboot常用的注解需要了解,开发必备
spring boot·后端
RoyLin4 小时前
C++ 基础与核心概念
前端·后端·node.js
aiopencode4 小时前
Charles 抓包 HTTPS 原理详解,从 CONNECT 到 SSL Proxying、常见问题与真机调试实战(含 Sniffmaster 补充方案)
后端
泉城老铁4 小时前
springboot 框架集成工作流的开源框架有哪些呢
spring boot·后端·工作流引擎
aloha_4 小时前
Ubuntu/Debian 系统中,通过包管理工具安装 Redis
后端
Java水解4 小时前
深入探索Spring:Bean管理与Spring Boot自动配置原理
后端·spring