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接口进行测试了
相关推荐
Arva .6 小时前
面试题02
后端
uzong10 小时前
一次慢接口背后,竟藏着40+种可能!你中过几个
后端·面试·程序员
G探险者11 小时前
滴滴P0级故障背后:互联网公司是如何分级处理线上事故的?
后端
G探险者11 小时前
从 Tomcat 与 Jetty 的对比,聊聊影响一个服务并发能力的关键因素
后端
你的人类朋友11 小时前
“签名”这个概念是非对称加密独有的吗?
前端·后端·安全
幼稚园的山代王12 小时前
go语言了解
开发语言·后端·golang
kkjt013012 小时前
{MySQL查询性能优化索引失效的八大场景与深度解决方案}
后端
ss27312 小时前
手写MyBatis第107弹:@MapperScan原理与SqlSessionTemplate线程安全机制
java·开发语言·后端·mybatis
橙子家13 小时前
log4net 简介以及简单示例(.net8)
后端
间彧13 小时前
Spring Boot分布式WebSocket实现指南:项目实战与代码详解
后端