news 2026/9/9 16:02:41

SpringBoot+Vue+MySQL前后端分离新闻资讯系统源码实操解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot+Vue+MySQL前后端分离新闻资讯系统源码实操解析

市面上打着“可直接运行”旗号的新闻资讯系统源码很多,但真正下载下来能一次跑通的其实不多。这套SpringBoot + Vue + MySQL的前后端分离项目算是我见过完成度比较高的,从管理员发布新闻、分类管理到前端门户展示、用户浏览,整个业务闭环是完整的,而且没有那些花里胡哨的微服务架构,就是最经典的单体后端加SPA前端,特别适合用来学习主流Java后端技术栈,也是毕业设计的高频选题。

这篇文章我会从代码结构、核心业务实现、环境搭建到常见坑位排查,把整套系统如何从零跑起来以及背后的设计逻辑拆开讲清楚。无论你是准备拿它来做课设、学习前后端分离开发模式,还是想在上面二次开发接私活,这篇应该都能帮你省掉不少时间。

1. 内容整体设计与思路拆解

1.1 这个项目解决了什么问题

先说说这个系统本身。新闻资讯系统信息管理系统,简单来说就是一个内容发布管理平台,核心用户有两类:一类是后台的管理员,负责维护新闻栏目分类、发布文章、管理公告;另一类是前台访客,浏览新闻列表、查看新闻详情、按分类筛选内容。

它的业务逻辑不复杂,但胜在完整。从软件工程的教学角度看,它覆盖了前后端分离开发的几乎所有关键环节:RESTful API设计、数据库建模、权限拦截、跨域处理、前端路由守卫、组件化开发这些都能在代码里找到对应实现。相比那些只有增删改查的“玩具项目”,这套系统明显更有诚意。

从实用角度看,这类系统在企业内部通知发布、中小型门户网站内容管理、甚至政务信息公开平台里都能找到影子。把它的代码吃透,你做其他内容管理类系统的上手速度会快很多,因为核心思路是通用的。

1.2 技术选型背后的理由

技术栈选SpringBoot + Vue + MySQL,可以说是当前Java后端入门最务实的一套组合。

SpringBoot能做到零XML配置启动Web服务,内嵌Tomcat,打一个jar包就能跑,这比起早期SSH框架省了太多配置成本,也符合现在微服务时代模块化开发的习惯。Vue作为前端框架,响应式数据绑定和组件化开发能让你用很轻量的方式实现数据驱动页面更新,配合Element UI这类组件库,后台管理界面可以做得又快又好看。MySQL则是最经典的关系型数据库,互联网公司中小型项目的主力,资料多、社区活跃,遇到问题基本都能搜到解决方案。

这套组合的另一个好处是招聘市场需求量大。你会发现很多中小型公司的技术栈就是SpringBoot + Vue + MySQL,会这套东西,你至少具备了快速融入团队的基础能力。

1.3 前后端分离模式的核心思想

所谓前后端分离,是指前端和后端各自独立开发、独立部署、通过HTTP接口通信。后端只负责业务逻辑和数据处理,返回JSON格式数据给前端;前端只负责页面渲染和用户交互,通过Axios发起异步请求获取数据。

项目里面,SpringBoot后端默认跑在8080端口,Vue前端开发服务器跑在5173(Vite)或8081(Webpack)之类的端口,两者通过HTTP协议交互。这就必然会碰到跨域问题——浏览器的同源策略会拦截不同端口的请求。项目里常见的解决方案是后端加CORS配置类或在Controller上加@CrossOrigin注解,前端Vite配置proxy代理转发。后面实操部分我会详细说这个。

当时我拿到这套源码,第一件事就是把整个项目的目录结构过了一遍,确认它是标准的前后端分离结构后才开始配置环境。我的建议是,你拿任何项目之前都不要急着启动,先把代码结构看清,这样后面遇到问题才有的放矢。

2. 核心细节解析与实操要点

2.1 后端SpringBoot工程结构拆解

后端源码的包结构分得很清楚。常见的是com.xxx.news下面拆controller、service、mapper、entity、config几个子包。Controller层负责接收前端请求和返回数据,Service层处理业务逻辑,Mapper层跟数据库打交道,Entity层对应数据表结构,Config层放置一些配置类,比如跨域配置、拦截器配置。

关键点在于Mapper层用了MyBatis还是MyBatis Plus。这两个差异挺大的。传统MyBatis需要手写XML映射文件,表的字段变更后要同步修改XML里的resultMap;MyBatis Plus则内置了通用的增删改查方法,大部分简单操作不用写SQL。我看这套系统用的是MyBatis Plus的自动填充功能,比如create_time、update_time这两个字段就是自动填充的,不需要手动set值。

实现自动填充的方式是定义一个MetaObjectHandler接口的实现类,重写insertFill和updateFill方法,在里面设置当前时间。代码大致是这样的:

@Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); } @Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); } }

对应的实体类字段上需要加@TableField(fill = FieldFill.INSERT)和@TableField(fill = FieldFill.INSERT_UPDATE)注解。这就是为什么你往数据库插入数据的时候,不需要手动传时间也能自动带上。

还有一个容易忽略的点,就是MyBatis Plus的分页插件需要手动配置,不配置的话分页查询会查出全部数据。配置方式是新建一个MybatisPlusConfig配置类,注册PaginationInnerInterceptor。你拿到源码后可以检查一下有没有这段配置,没有的话要自己加上:

@Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }

2.2 前端Vue工程结构与页面流转

前端部分用的是Vue全家桶。入口文件main.js里,通过createApp(App)创建Vue实例,同时全局注册了Element UI组件库、Pinia或Vuex状态管理、Vue Router路由。如果项目用的是Vue 3,那大概率配的是Vite构建工具,开发启动命令是npm run dev;如果是Vue 2,那用webpack,命令是npm run serve。

页面路由设计上,一般分为两块:面向游客的portal(门户)页面和面向管理员的后台管理页面。门户页面有首页新闻列表、新闻详情、分类浏览;后台有登录页、控制台、新闻管理、分类管理等。这两类页面通过路由的元信息(meta)和导航守卫做访问控制,比如后台页面要求必须带着token才能进入。

前端组件化是这套代码的一个亮点。新闻列表、新闻卡片、分页组件、评论列表这些都被拆成了独立Vue组件,通过props接收数据、通过emit向父组件抛事件。比如新闻详情页通常会引入一个CommentList组件,评论提交成功后,子组件把事件抛给父组件,父组件重新拉取评论数据刷新列表。

前端环境安装这块是很多人第一次跑项目的大坑。建议Node.js装16或18的LTS版本,版本太高或太低都容易出依赖兼容问题。装好之后在项目根目录执行npm install安装依赖,如果是在国内网络环境下,记得先把npm源切换到淘宝镜像:

npm config set registry https://registry.npmmirror.com

如果不换源,node-sass这类依赖下载会卡到你怀疑人生。另外注意package.json里的依赖声明,如果里面写着"node-sass",这玩意儿对Node版本非常敏感,你要是Node版本过新,构建会报错。遇到这种情况,要么降Node版本,要么把它改成"sass"(dart-sass),代码不用改,构建就正常。

2.3 数据库表设计与初始化

数据库初始化脚本一般放在源码根目录下的sql文件夹里,文件名叫init.sql或news.sql。导入之前你需要先在MySQL里建一个空数据库,比如CREATE DATABASE news DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;然后再source导入脚本。

表结构设计上,核心的表至少有这几张:

用户表sys_user存管理员账号,字段包括用户名、密码(BCrypt加密后的密文)、昵称、头像、状态等。密码加密方面,SpringSecurity或Sa-Token框架一般内置BCryptPasswordEncoder,加密后的密码形如$2a$10$......,你直接用明文去数据库里对比肯定验不过。

新闻资讯表news_info是核心业务表,字段包括标题、摘要、正文内容、封面图URL、分类ID、作者、发布时间、状态(草稿/已发布)等。状态字段很关键,前台页面查询时必须要过滤掉草稿状态,只展示已发布内容。

分类表news_category存新闻栏目,比如国内新闻、国际新闻、科技新闻、体育新闻等,通过sort字段控制排序。

评论表news_comment记录用户对新闻的评论,关联新闻ID和用户ID。

这几张表之间通过外键逻辑关联,但实际开发中很多人不会在数据库层面真建外键约束,而是靠业务代码保证数据一致性,因为外键对性能有影响,而且在分布式场景下会带来麻烦。这套代码也是这个风格,表之间用字段逻辑关联,删除新闻时业务代码里手动把对应评论也删掉。

2.4 后端跨域处理与安全配置

跨域是个必聊的话题。开发模式下,前端在5173端口,后端在8080端口,前端请求后端接口,浏览器判定这属于跨域调用,默认会拦截。

这个项目里通常用两种方式解决。一种是在后端写一个CorsConfig类实现WebMvcConfigurer接口,重写addCorsMappings方法,允许所有来源访问:

@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }

另一种是开发环境下前端Vite配置proxy代理,原理是让前端开发服务器把/api开头的请求转发给后端,浏览器看到的是同源请求,就不存在跨域了。两种方案各有好处,后端配置CORS适合前后端分开部署的生产环境;前端代理只在开发模式下有效,生产环境还是要靠后端放行。

安全这块,系统一般集成了Sa-Token或者SpringSecurity做登录认证和接口权限控制。以Sa-Token为例,用户登录成功后拿到一个token,后续请求在请求头里带上token,后端通过拦截器解析token校验身份。后台管理接口需要管理员权限,拦截器里判断当前登录用户的角色,没有权限直接返回401。这个逻辑在拦截器配置类里可以看到,通常是继承SaInterceptor或者实现HandlerInterceptor。

3. 实操过程与核心环节实现

3.1 环境准备清单

提前把环境装好能省去后面80%的麻烦。先说版本,我建议的搭配是这样的:

JDK用1.8或11都行,但如果你用的SpringBoot版本是2.7以上,建议JDK 11起步。SpringBoot 3.x要求JDK 17,这个要注意看项目pom.xml里spring-boot-starter-parent的版本号。

Maven用3.6以上版本,IDEA里配置好仓库镜像到阿里云,不然依赖下载会让你等到崩溃。

MySQL建议装8.0版本,5.7也可以,但pom.xml里的mysql-connector-java版本要对应上。8.0版本的驱动类名是com.mysql.cj.jdbc.Driver,5.7用com.mysql.jdbc.Driver,驱动包版本不对会报ClassNotFoundException。

Node.js装16.20.2这个版本最稳妥,装完把npm源切到淘宝镜像。

开发工具方面,后端用IDEA,前端可以用IDEA也可以VSCode,数据库工具用Navicat或者IDEA自带的Database面板都行。

3.2 后端启动完整步骤

先把项目源码解压到一个没有中文和空格路径的目录里,比如D:\projects\news-system。这个细节很多人不注意,路径里有中文的话,Maven打包偶尔会出奇怪的编码问题。

用IDEA打开后端文件夹(一般叫news-server或server),打开后会提示你加载Maven项目,等依赖下载完成。然后在src/main/resources/application.yml里修改数据库连接信息:

server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/news?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false username: root password: 你的数据库密码 driver-class-name: com.mysql.cj.jdbc.Driver

注意url里这些参数的含义:useUnicode=true和characterEncoding=utf8保证中文不乱码;serverTimezone=Asia/Shanghai指定时区,不然连MySQL 8.0的时候会报时区错误;useSSL=false关掉SSL证书验证。

启动前确保MySQL服务已启动、数据库已导入、账号密码正确。然后运行主启动类,看到类似"Started NewsApplication in x.x seconds"的日志就说明后端起来了。验证方式很简单,浏览器访问http://localhost:8080/,能看到一段JSON说明SpringBoot正常返回,访问http://localhost:8080/api/news/list这种实际接口能返回数据,说明数据库连接也没问题。

3.3 前端启动完整步骤

前端文件夹一般叫news-ui或web。用IDEA或VSCode打开,在终端执行npm install。这个过程时间长短取决于网络状况,装完后执行npm run dev或npm run serve。

如果启动成功,终端会打印出本地访问地址,通常是http://localhost:5173/。打开浏览器看到首页,但这时候页面数据可能还是空的,因为前端请求的接口地址还没配通。

前端请求后端地址的配置一般在两个地方:Vite的vite.config.js或vue.config.js里面的proxy配置,以及src/utils/request.js里Axios的baseURL。开发模式下走代理是最省事的,配置这样写:

// vite.config.js export default defineConfig({ server: { port: 5173, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } } })

这样前端请求/api/news/list,就会被代理转发到http://localhost:8080/api/news/list,既解决跨域,又保持代码里接口路径的相对一致性。

3.4 从登录到数据流全链路走通

整个系统能不能跑通,最直观的验证方式就是走一遍完整的用户操作链路。我建议按这个顺序测试:

打开前台门户首页,能看到新闻列表正常展示,新闻封面图正常加载。点击一篇新闻进入详情页,能看到正文内容和评论列表,如果没登录就提交评论,系统应该提示你先登录。

进入后台登录页,用源码里自带的管理员账号登录(一般是admin/123456或admin/admin123,具体看sql脚本里的初始化数据)。登录成功后进入管理界面,尝试发布一篇新新闻,填标题、选分类、传封面图、写正文,保存,然后回到前台首页刷新,能看到这篇新闻出现在列表里。

这条链路走通,说明你的前端路由、后端接口、数据库读写、文件上传存储全部正常。上传图片这里有个小知识点:图片一般有两种存法,一种是本地磁盘路径,后端把文件保存到本地某个目录,然后通过静态资源映射让前端能访问;另一种是存OSS对象存储服务。这套源码大概率是本地存储,配置文件里可能有个upload.path之类的参数,图片上传后的访问路径是这个参数拼上文件名。

注意如果上传图片后前端显示不出来,多半是上传目录和静态资源映射没对上,或者相对路径写死了localhost:8080,你改过端口导致访问不到。

4. 常见问题与排查技巧实录

4.1 数据库连接相关报错

数据库连接是报错重灾区。驱动类找不到,大概率是依赖没下完整或者版本不对;Access denied for user说明用户名密码错;Unknown database说明数据库没建;Communications link failure说明MySQL服务没启动或url里端口不对。

这里特别说一下时区问题。很多人导入数据库后启动后端报这个错:

The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone

这就是在url里没加serverTimezone=Asia/Shanghai导致的。还有一种情况是mysql-connector-java的版本和MySQL服务器版本差太远,5.x驱动连8.x数据库会有兼容警告,建议驱动版本和数据库版本保持一致或略高。

排查技巧:不要光看报错最后一行,往上翻异常堆栈,找到Caused by那一行,那才是根因。很多新手被一堆报错信息吓住,其实Caused by一行就说明问题了。

4.2 前端访问后端接口报404或500

访问接口报404,先确认后端那个接口路径是否跟前端请求路径完全一致。用浏览器的开发者工具看Network面板,找到这条请求,对照Controller里的@RequestMapping路径。最容易出错的地方是漏了Context Path,比如你在application.yml里配置了server.servlet.context-path: /news,那么所有接口的访问路径都得加上这个前缀,前端代理和目标地址都要对应改。

报500则基本是后端代码执行出错,看后端控制台或日志文件里的异常堆栈。常见的是SQL写错、字段类型映射不对、空指针这几种。如果是查询数据时报SQLSyntaxErrorException,检查实体类字段名和数据表字段名是否一致,MyBatis Plus的下划线转驼峰映射没有全局开启的话,字段名对不上就会报错。

4.3 前端依赖安装失败

npm install时最常见的报错有几种:node-sass安装失败、网络超时、依赖版本冲突。node-sass的问题前面说过,改成sass就好;网络问题换淘宝镜像或设置代理;版本冲突一般出现在package-lock.json里锁定的版本跟你本机Node不兼容,最简单的办法是把node_modules目录和package-lock.json删掉,重新npm install。

还有一个很隐蔽的问题是npm cache损坏,安装到一半进程被杀掉容易导致缓存异常,可以执行npm cache clean --force再重装。

4.4 前端页面样式错乱或组件库不生效

页面能渲染但样式不对,常见原因是Element UI按需引入配置出问题,或者全局样式覆盖了组件库样式。检查main.js里是否正确引入了Element Plus的样式文件。如果你用的是Element Plus,全局引入就写:

import ElementPlus from 'element-plus' import 'element-plus/dist/index.css'

如果是按需自动引入,用unplugin-vue-components插件,这个插件会在编译时自动把用到的组件和样式打包进去,如果配置漏了样式转译那一步,就会出现“组件功能正常但没样式”的情况。

4.5 登录后token失效或登录状态丢失

登录成功后跳转回登录页,这通常有三个原因。第一,后端返回的token没被前端正确保存,检查登录接口拿到数据后是不是存到了localStorage或sessionStorage;第二,Axios请求拦截器里没把token塞进请求头,后端校验不到token就会返回401;第三,路由守卫的判空逻辑有问题,比如用responsive的方式判断token是否存在时用了错误的字段名。

我建议你在浏览器开发者工具的Application面板里看一下localStorage里到底有没有token值,有的话再看Network面板里接口请求的Headers里有没有Authorization字段。这样一段段排查,很快能定位是哪一环断了。

4.6 项目启动顺序与端口占用问题

后端和前端有没有固定的启动顺序?严格来说没有,你想先起哪个都行,反正两边是通过HTTP通信的,你只要保证测试时两个服务都在运行就行。但我个人的习惯是先起后端,因为前端页面上看一眼就要调接口,后端起来了我好提前确认数据接口正常。

端口被占用也是高频问题。启动前端时提示Port 5173 is in use,说明有别的进程占了这个端口。Windows下用netstat -ano | findstr 5173查看占用进程PID,然后taskkill /PID 进程号 /F杀掉;也可以直接改vite.config.js里的端口配置。后端8080被占用同理,改application.yml里的server.port即可,但要注意前端代理target的端口也要同步改。

4.7 数据库字符集设置

中文乱码问题要是出现,先别急着改代码,大概率是数据库表结构的问题。建库用utf8mb4,建表也要指定utf8mb4字符集,连接url里加上characterEncoding=utf8,这三个地方全都对了才不会乱码。如果是已经导入的库出现乱码,用ALTER TABLE xxx CONVERT TO CHARACTER SET utf8mb4;转换一下。

区分utf8和utf8mb4是MySQL里的老生常谈。utf8在MySQL里最多3字节,存emoji或生僻字就会失败报错;utf8mb4是完整的Unicode实现,4字节,任何字符都能存。现在的项目一律建议utf8mb4,别再用utf8了。

5. 二次开发建议与进阶方向

5.1 可以扩展的功能点

这套系统跑通之后,我建议你别停在“能运行”就完事了,往里面加几个功能,对理解项目的帮助会非常大。

比如加一个浏览记录功能。同一IP或同一用户访问新闻详情时,往浏览记录表里插入一条数据,如果已存在则更新时间。这个功能看似简单,实际要处理高并发下的重复插入问题、数据量大后的清理策略,这些都很有实战价值。

比如加一个新闻关键字搜索功能。最简单的方案是MySQL的LIKE模糊查询,sql里写where title like concat('%', keyword, '%'),数据量小完全够用。数据量上来后可以优化为fulltext全文索引,或者引入Elasticsearch,但那是另一套架构了。

再比如给新闻表加一个浏览量字段,每次点击详情时+1。这个方案在高并发下有性能问题,你会接触到Redis原子自增、异步刷盘这些优化手段,也是面试常问的场景。

5.2 生产部署要考虑的问题

如果要把这套系统部署到云服务器上,有几个东西要改。

前端需要执行npm run build打包,生成dist目录,里面是纯静态文件,可以丢到Nginx的html目录里,也可以用docker镜像里挂一个nginx容器来服务。后端打成可执行jar包,用java -jar news.jar命令启动,生产环境建议用systemd或supervisor托管,保证进程崩溃后能自动拉起。

数据库层面,需要把数据库脚本导出,在服务器上重新导入一遍,同时修改后端配置文件里的数据库连接为服务器的MySQL地址。

注意生产环境的跨域配置。前端部署到Nginx后,浏览器访问的是Nginx的80端口,后端跑在8080,还是跨域。两种解法:Nginx配置反向代理,把/api路径转发到本机的8080端口;或者后端开启CORS,把allowedOriginPatterns配置为你的前端域名。

5.3 学习路径建议

如果你是个后端方向的学生或初级开发者,我建议的学习顺序是:先看懂整个项目的请求流转链路,从浏览器地址栏输入URL到页面最终渲染,这一步你画一张流程图出来,把所有环节串起来,你对全栈开发的理解会上一个台阶。

然后专注于某个模块纵向深入。比如新闻发布这个模块,从前端表单校验、文件上传到后端接收、参数校验、数据库落库,整个链路里的每一行代码都看懂,再想想哪里有漏洞、哪里性能可以优化,这种纵向深挖比横向看十个项目都有效。

最后是动手改代码。改一个字段、加一个接口、调一个Bug,都比看十遍源码来得实在。这套项目本来就是开箱即用的,非常适合边跑边改边验证。

我在实际跑这套项目的时候最大的感受是,它不只是一个“能运行”的源码,而是一套完整的教学素材。你把里面每个注解、每个配置文件、每个拦截器都弄清楚,SpringBoot + Vue这套主流组合的核心知识算是掌握得差不多了。下一步哪怕是去面实习岗,聊到项目经验的时候,能把这个系统的表结构设计思路、权限控制的实现方式、跨域处理的两种方案讲明白,面试官基本就能确认你是真的动过手写代码的人。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 16:01:27

Gemini API JSON文本摘要实战指南:一次调用把长文变成结构化数据

Gemini API JSON文本摘要实战指南:一次调用把长文变成结构化数据 【免费下载链接】cookbook Examples and guides for using the Gemini API 项目地址: https://gitcode.com/GitHub_Trending/coo/cookbook 处理小说、报告、产品描述这类长材料时,…

作者头像 李华
网站建设 2026/9/9 15:58:58

软件测试面试深度剖析:高频考点与实战应对策略

1. 软件测试面试到底在考什么每年一到金三银四、金九银十,我后台收到最多的私信就是“测试面试题有没有整理好的版本”或者“有没有软件测试面试必背100例”。说实话,这类资料网上不缺,缺的是能把题目背后的考察逻辑讲清楚的内容。很多人背了…

作者头像 李华
网站建设 2026/9/9 15:57:21

安卓Recovery无人值守自动擦除:AOSP源码与BCB命令实战

1. 项目缘起:这需求到底要解决什么问题这段时间手头一直在做安卓设备的定制化改造,客户提了个很实际的需求:设备从产线下来,或者从租户手里收回来之后,需要保证里面的历史数据被彻底清掉。以前靠人手动进Recovery模式&…

作者头像 李华
网站建设 2026/9/9 15:56:08

C语言文件操作核心指南:流、缓冲区与读写API实战

不知不觉,文件操作成了很多C语言学习者的一道坎。数组、指针、结构体还能在终端里跑跑看,可一旦涉及文件读写,就完全进入另一套逻辑。这几天后台收到不少“C语言文件操作”相关的问题:有人问我fscanf和fprintf为什么老用不对&…

作者头像 李华
网站建设 2026/9/9 15:53:49

5分钟把数据库变成自然语言问答助手:WrenAI 新手实操教程

5分钟把数据库变成自然语言问答助手:WrenAI 新手实操教程 【免费下载链接】WrenAI GenBI (Generative BI) for AI agents, an open-source, governed text-to-SQL through an open context layer that turns natural-language questions into trusted dashboards, c…

作者头像 李华