Springboot后端管理项目+AI剑指数据可视化分析
传统模式 vs 智能革命:用AI让数据「随想随看」传统时代的困境:企业每天都有上百个数据统计需求——销售想对比各区域业绩趋势,财务要分析成本波动原因,管理层需实时查看经营指标… 但每个需求都像一场漫长的接力赛:1️⃣ 业务人员绞尽脑汁写需求文档,还得懂技术术语(“要LEFT JOIN哪几个表?GROUP BY什么字段?”)2️⃣ 程序员熬夜写SQL、改代码,一个简单需求从提出到上线平均
拥抱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
更多推荐
所有评论(0)