拥抱AI

在这里插入图片描述

后端管理系统现状

传统模式 vs 智能革命:用AI让数据「随想随看」
‌传统时代的困境:‌
企业每天都有上百个数据统计需求——销售想对比各区域业绩趋势,财务要分析成本波动原因,管理层需实时查看经营指标… 但每个需求都像一场漫长的接力赛:
1️⃣ ‌业务人员‌绞尽脑汁写需求文档,还得懂技术术语(“要LEFT JOIN哪几个表?GROUP BY什么字段?”)
2️⃣ ‌程序员‌熬夜写SQL、改代码,一个简单需求从提出到上线平均耗时3天
3️⃣ ‌上线后‌却发现指标计算逻辑不对,又要返工重来…

‌更糟的是:‌
✅ 系统里预置的报表模板用半年就过时
✅ 突发分析需求只能等排期开发
✅ 程序员30%时间在写重复的统计代码

‌AI如何破局?‌
想象这样的场景:

销售总监在系统输入:“帮我找出过去3个月华东区退货率超5%的商品,按城市和渠道分类对比”
‌AI语义引擎‌自动解析需求,1秒生成精准SQL(智能规避慢查询、自动关联多表)
‌智能连接器‌直连数据库,2秒返回统计结果
‌自适应看板‌自动选择最佳图表——折线图呈现趋势,热力图展示区域对比,还可拖拽调整布局
‌这意味什么?‌
▸ 业务人员‌告别技术黑话‌,像对话一样获取数据
▸ 开发团队‌节省90%重复劳动‌,专注复杂业务逻辑
▸ 企业决策‌响应速度提升10倍‌,突发分析随时开展
▸ 系统报表‌永不过时‌,千人千面的数据洞察触手可得

‌真实案例:‌
某连锁企业接入AI分析系统后:
◼ 临时报表开发需求从每月120个降至6个
◼ 区域经理自主完成销售分析的占比从15%飙升至83%
◼ 双十一大促期间,实时战报更新速度从2小时缩短到30秒

当数据需求不再受限于技术资源,当每个业务人员都能成为「数据分析师」,这才是数字化转型该有的样子。

普通后端管理系统+AI怎么落地实现

示例接入大模型为免费的智谱AI大模型

在这里插入图片描述

大模型千千万,特别是最多的国产之光–Deepseek更强大;按照企业需求来,这里做演示就用开源免费的质谱接口吧

为什么选择它,因为人家是免费的,别的要么你付费,要么你私有化部署吧

在这里插入图片描述
更多功能探索–使用AI能力,看它的官网:https://bigmodel.cn/dev/activities/free/glm-4-flash;

核心就是你整理好问题的描述,丢给AI,拿到的AI返回的结果,然后去执行对应的查询获取结果。

示例问题:
请你作为数据分析师,现在数据库的表结构是这样:CREATE TABLE `sys_user` (
  `user_id` bigint(20) NOT NULL COMMENT '用户ID',
  `tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',
  `dept_id` bigint(20) DEFAULT NULL COMMENT '部门ID',
  `user_name` varchar(30) NOT NULL COMMENT '用户账号',
  `nick_name` varchar(30) NOT NULL COMMENT '用户昵称',
  `user_type` varchar(10) DEFAULT 'sys_user' COMMENT '用户类型(sys_user系统用户)',
  `email` varchar(50) DEFAULT '' COMMENT '用户邮箱',
  `phone_number` varchar(11) DEFAULT '' COMMENT '手机号码',
  `sex` char(1) DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)',
  `avatar` bigint(20) DEFAULT NULL COMMENT '头像地址',
  `password` varchar(100) DEFAULT '' COMMENT '密码',
  `status` char(1) DEFAULT '0' COMMENT '帐号状态(1正常 0停用)',
  `del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
  `login_ip` varchar(128) DEFAULT '' COMMENT '最后登录IP',
  `login_date` datetime DEFAULT NULL COMMENT '最后登录时间',
  `create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
  `create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `remark` varchar(500) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='用户信息表';帮助查询出2024年创建的用户信息有哪些?,具体输入的内容为标准的SQL即可。

示例AI结果:
{
	"choices": [{
		"finish_reason": "stop",
		"index": 0,
		"message": {
			"content": "sql\nSELECT *\nFROM sys_user\nWHERE YEAR(create_time) = 2024;\n",
			"role": "assistant"
		}
	}],
	"created": 1743233784,
	"id": "2025032915362465b1dae5c96f44c4",
	"model": "glm-4-flash",
	"request_id": "guo_tong_1743233890584",
	"usage": {
		"completion_tokens": 22,
		"prompt_tokens": 499,
		"total_tokens": 521
	}
}

拿到自然语言转化后的SQl,查询数据库还不会嘛。。。。。

在这里插入图片描述

Springboot+AI完整示例:

要不要引入各种AI的jar脚手架,看需要,我这里直接用Http的方式交互不需要第三方AI的jar哈

package com.gt.quality.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSONUtil;
import com.gt.quality.config.ZhiPuAIConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 万里悲秋常作客,百年多病独登台
 *
 * @author : makeJava
 */
@RestController
@RequestMapping("/ai")
@Slf4j
@SaIgnore
public class ZhiPuAiController {


    // 请自定义自己的业务id
    private static final String REQUEST_ID_TEMPLATE = "guo_tong_%d";

    private static final String COMPLETIONS_URL = "https://open.bigmodel.cn/api/paas/v4/chat/completions";


    @Value("${spring.datasource.url}")
    private String dbUrl;

    @Value("${spring.datasource.username}")
    private String dbUsername;

    @Value("${spring.datasource.password}")
    private String dbPassword;

    /**
     * 同步调用
     */
    @RequestMapping("/zhi_pu_qa")
    public String testInvoke(@RequestParam(value = "question", defaultValue = "2024年创建的用户信息有哪些?", required = false) String question) {
        Map<String, Object> body = new HashMap<>();
        body.put("model", "glm-4-flash");
        List<Map<String, Object>> messages = getMapList(question);
        body.put("messages", messages);
        body.put("request_id", String.format(REQUEST_ID_TEMPLATE, System.currentTimeMillis()));
        body.put("do_sample", true);
        body.put("stream", false);
        body.put("temperature", 0.95);
        body.put("max_tokens", 4095);
        Map<String, Object> responseFormat = new HashMap<>();
        responseFormat.put("type", "json_object");
        body.put("response_format", responseFormat);
        // function、retrieval、web_search。
        body.put("type", "web_search");

        String result = "null";
        try (HttpResponse response = HttpUtil.createRequest(Method.POST, COMPLETIONS_URL)
                .body(JSONUtil.toJsonStr(body))
                .header("Authorization", "Bearer " + ZhiPuAIConstant.ZHI_PU_AI_API_KEY)
                .execute()) {
            // 使用 try-with-resources 确保资源自动关闭
            result = response.body();
        } catch (Exception e) {
            log.error("调用接口失败: {}", e.getMessage(), e);
            return "接口调用失败,请检查日志!";
        }
        log.info("调用接口返回: {}", result);
        // 解析获取到的SQL
        String sql = parseSqlFromResponse(result);
        if (sql == null) {
            return "解析SQL失败,请检查AI返回的内容!";
        }
        // 调用JDBC连接执行该SQL拿到结果
        List<Map<String, Object>> resultList = executeSql(sql);

        // 将结果转换为JSON字符串返回
        return JSONUtil.toJsonStr(resultList);
    }

    private static List<Map<String, Object>> getMapList(String question) {
        List<Map<String, Object>> messages = new ArrayList<>();
        Map<String, Object> msgItem = new HashMap<>();
        msgItem.put("role", "user");
        msgItem.put("content", "请你作为数据分析师," +
                               "现在数据库的表结构是这样:CREATE TABLE `sys_user` (\n" +
                               "  `user_id` bigint(20) NOT NULL COMMENT '用户ID',\n" +
                               "  `tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',\n" +
                               "  `dept_id` bigint(20) DEFAULT NULL COMMENT '部门ID',\n" +
                               "  `user_name` varchar(30) NOT NULL COMMENT '用户账号',\n" +
                               "  `nick_name` varchar(30) NOT NULL COMMENT '用户昵称',\n" +
                               "  `user_type` varchar(10) DEFAULT 'sys_user' COMMENT '用户类型(sys_user系统用户)',\n" +
                               "  `email` varchar(50) DEFAULT '' COMMENT '用户邮箱',\n" +
                               "  `phone_number` varchar(11) DEFAULT '' COMMENT '手机号码',\n" +
                               "  `sex` char(1) DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)',\n" +
                               "  `avatar` bigint(20) DEFAULT NULL COMMENT '头像地址',\n" +
                               "  `password` varchar(100) DEFAULT '' COMMENT '密码',\n" +
                               "  `status` char(1) DEFAULT '0' COMMENT '帐号状态(1正常 0停用)',\n" +
                               "  `del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',\n" +
                               "  `login_ip` varchar(128) DEFAULT '' COMMENT '最后登录IP',\n" +
                               "  `login_date` datetime DEFAULT NULL COMMENT '最后登录时间',\n" +
                               "  `create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',\n" +
                               "  `create_by` bigint(20) DEFAULT NULL COMMENT '创建者',\n" +
                               "  `create_time` datetime DEFAULT NULL COMMENT '创建时间',\n" +
                               "  `update_by` bigint(20) DEFAULT NULL COMMENT '更新者',\n" +
                               "  `update_time` datetime DEFAULT NULL COMMENT '更新时间',\n" +
                               "  `remark` varchar(500) DEFAULT NULL COMMENT '备注',\n" +
                               "  PRIMARY KEY (`user_id`) USING BTREE\n" +
                               ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='用户信息表';帮助查询出" + question + ",具体输入的内容为标准的SQL即可。");
        messages.add(msgItem);
        return messages;
    }

    /**
     * 从AI返回的JSON中解析SQL
     *
     * @param response AI返回的JSON字符串
     * @return 解析后的SQL字符串
     */
    @SuppressWarnings("unchecked")
    private String parseSqlFromResponse(String response) {
        try {
            Map<String, Object> responseMap = JSONUtil.toBean(response, Map.class);
            List<Map<String, Object>> choices = (List<Map<String, Object>>) responseMap.get("choices");
            if (choices != null && !choices.isEmpty()) {
                Map<String, Object> choice = choices.get(0);
                Map<String, Object> message = (Map<String, Object>) choice.get("message");
                if (message != null) {
                    String content = (String) message.get("content");
                    if (content != null) {
                        if (content.startsWith("\n{")) {
                            Map<String, Object> contentMap = JSONUtil.toBean((String) message.get("content"), Map.class);
                            Object answer = contentMap.get("answer");
                            if (answer!=null){
                                return answer.toString();
                            }
                            Object sqlQuery = contentMap.get("sql_query");
                            return Objects.requireNonNullElse(sqlQuery, contentMap).toString();
                        }
                        content = content.replace("sql\n","");
                        return content;
                    }

                }
            }
        } catch (Exception e) {
            log.error("解析JSON失败: {}", e.getMessage(), e);
        }
        return null;
    }

    /**
     * 通用执行Ai 生成的SQL
     *
     * @param sql sql
     * @return List<Map < String, Object>>
     */
    private List<Map<String, Object>> executeSql(String sql) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        try (Connection connection = DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
             Statement statement = connection.createStatement();
             ResultSet resultSet = statement.executeQuery(sql)) {

            int columnCount = resultSet.getMetaData().getColumnCount();
            while (resultSet.next()) {
                Map<String, Object> row = new HashMap<>();
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = resultSet.getMetaData().getColumnName(i);
                    Object columnValue = resultSet.getObject(i);
                    row.put(columnName, columnValue);
                }
                resultList.add(row);
            }
        } catch (Exception e) {
            log.error("执行SQL失败: {}", e.getMessage(), e);
        }
        return resultList;
    }


    /**
     * sse调用
     */
    @RequestMapping("/zhi_pu_say")
    public SseEmitter testSseInvoke() {

        return new SseEmitter();
    }
}

数据库的表越详细越好,注释越详细越好!!然后就是查询表结构带给Ai,然后加上问题给AI,AI生成SQL哟。

示例—问题

2024年创建的用户中男性和女性的占比情况

在这里插入图片描述

用户手机号是15837357332的有那些人

在这里插入图片描述

逻辑删除掉的用户按照创建时间倒叙返回前三条数据,只列举名称和创建时间

在这里插入图片描述

想怎么问就怎么问,什么都可以。。。。AI加持—YYDS

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐