MIT License

技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

用 Go 单挑一个后台:RuoYi-Go 的取舍与野心

项目背景与痛点

在 Java 生态里,若依(RuoYi)几乎是后台管理脚手架的"事实标准":一套权限模型、一部代码生成器、若干张字典表,能让人在两天内交付一个带菜单、部门、日志、定时任务的完整后台。而当开发者转向 Go,问题就暴露出来了。

Go 侧的 admin 脚手架大致分成两派。一派以 gin-vue-admin 为代表,强前后端分离、插件化、生态活跃;另一派把查询能力全权交给 GORM 的链式 API。前者对一个人做内部系统来说太重,还得同步维护 Vue 工程;后者在应付多表关联、动态条件、报表统计时很快力不从心,最终往往退化成在 Go 代码里拼 SQL 字符串,可读性与可维护性出现突然下降。

RuoYi-Go 的位置很明确:gin + gorm 的骨架,MyBatis 式的 SQL 与代码分离,传统模板引擎渲染。它默认只服务于一种人:那个既要写接口、又要写页面、还得管数据库的后端开发。

核心技术揭秘

分层结构与 Java 版若依高度对应:Controller → Service → Mapper(DAO),让从若依迁移过来的人零成本上手。真正的技术难度在 Mapper 层之下的 SQL 引擎。

SQL 与代码分离是怎么实现的

SQL 不写在 Go 代码里,而是以 XML/资源文件的形式独立存放,启动时扫描加载并缓存。要跑通这套机制,得自己实现一个轻量级的 MyBatis:

  1. 占位符体系:#{} 走预编译参数绑定,${} 做字符串直拼(留给表名、排序字段这类无法参数化的位置,也是注入风险的确切边界);
  2. 动态标签:if、choose、foreach、where、set 需要被解析成一棵可裁剪的语法树,运行时按入参决定保留哪些片段、如何拼接 AND/OR 前缀;
  3. 结果映射:查询结果的列名(dept_id)需要经反射映射到结构体字段(DeptId),靠 tag 与命名转换规则对齐。

关键取舍在于:最终 SQL 仍然交给 GORM 执行。 GORM 在这里被降级为连接池管理与结果扫描器,通过 Raw() + Scan() 完成调用,不再承担查询构建职责。这既保留了 SQL 的完全控制权,又没有重复造轮子。

graph TD A[HTTP 请求] --> B[Gin 路由与中间件] B --> C{"鉴权与权限校验"} C -->|"通过"| D[Controller 控制器] C -->|"拒绝"| E[统一错误响应] D --> F[Service 业务层] F --> G[Mapper 数据访问层] G --> H[SQL 模板解析器] H --> I{"存在动态标签"} I -->|"是"| J[按运行时参数裁剪] I -->|"否"| K[直接取用静态 SQL] J --> L[预编译参数绑定] K --> L L --> M[GORM Raw 执行] M --> N[反射映射结果集] N --> F F --> O[模板引擎渲染] O --> P[返回 HTML 页面]

另一个隐藏难点是数据权限。若依的经典做法是 @DataScope 注解 + AOP,在运行时向 SQL 追加 dept_id IN (...)。Go 没有注解,也没必要引入重量级 AOP,可行的路径是让 Mapper 层在解析 SQL 后注入权限片段。这意味着模板解析器必须支持"外部片段注入"这种扩展点,而这恰恰是很多同类项目没能做透的地方。

功能亮点与差异

杀手锏一:不让 ORM 代替你写 SQL。 报表、多表关联、分页聚合这类场景,SQL 文件里的可读性远胜一串链式调用,且能直接被 DBA 审阅。

杀手锏二:后端模板渲染。 不需要 Node 构建链路,编译产物加静态资源即可部署,一台服务器、一个二进制、一份配置,运维负担降到最低。这在交付压力大的内网项目里是巨大优势。

杀手锏三:功能与若依生态对齐。 用户、角色、菜单、部门、字典、参数、操作日志、代码生成器一应俱全,与 gin-vue-admin 的"全栈分离、插件扩展"路线形成清晰分工。

应用场景与落地建议

适合:企业内部管理系统、CRUD 密集的中后台、报表统计、内网系统、从 Java 若依迁移的项目,以及个人独立承担的交付型项目。

不适合:面向 C 端的高并发服务、需要多端复用(小程序/App)的业务——模板渲染天然拿不到那一份 API 复用红利。

生产环境的几个注意事项:

  • 关掉 SQL 文件热加载。开发期的便利在生产就是风险源,误改一次 SQL 等于线上事故。
  • ${} 必须走白名单。表名、排序字段这些直拼位置,靠代码层枚举校验,不要相信前端传参。
  • 解析层压测。反射映射加字符串拼接,在高频接口上有明确的性能开销,必要时缓存解析后的 SQL 片段。
  • 模板转义。html/template 默认转义,text/template 不转义,混用容易留下 XSS 入口。
  • 事务要统一封装。跨 Mapper 的手工事务若无统一入口,很容易出现漏提交与连接泄漏。

综合评价

优点:SQL 可控、交付快、迁移平滑、心智负担低。它承认了一个朴素事实——大多数后台系统的瓶颈不在框架的抽象层次,而在业务能否被快速、正确地写出来。

缺点同样明显:社区与文档厚度远不及 Java 原版,遇到解析器边界问题基本只能自己看源码;模板渲染的前端体验停留在传统 MVC 水准;动态 SQL 解析的健壮性高度依赖作者的实现功力;缺少微服务、云原生方向的演进规划。

一句话总结:它不是给架构师炫技的框架,是给后端老实人干活的框架。 如果你的项目是"一个人、几个月、一个内网后台",它几乎踩在最优解上;如果要做长期演进的多端产品,请直接跳过。

简要分析

热度分
402
价值分
180
活跃状态
活跃

语言占比

CSS
Go
Go Template
Makefile
Shell

Release

README

logo

ruoyi-go

Go语言版轻量级快速开发框架

框架简介

摒弃过度封装,代码风格极尽简洁,适合中小项目使用!
架构思路沿袭着若依的以辅助生成重复代码为主,不过度封装,生成的代码可以快速修改适应不同的需求。

  • 项目结构模仿springboot,简单改造后可注册到nacos中做为springcloud微服务的一员,对java开发人员友好。
  • 支持类mybatis查询,sql与go代码分离(基于gorm + golang的template语法实现,为了idea能识别sql关键字,后缀使用_mapper.sql)。
  • 提供相关服务配置脚本,可发布到 k8s、docker swarm中做为微服务使用。
  • 支持在yaml文件中使用表达式从环境变量中取值,便于切换生产、开发、测试环境参数(模仿springboot),如:
    host: ${REDIS_HOST:lostvip.com}
    如: 环境变量添加 REDIS_HOST=192.168.88.114;REDIS_PORT=6379;REDIS_PWD=dpctest

核心技术及组件

  • DAO层框架: gorm,简单易用,支持namedSQL占位符查询.
  • Web服务框架: Gin 简单高效,模板可热加载.
  • 前端技术: 模板引擎,服务端渲染.
  • 缓存支持: redis .
  • 安全认证:支持通过jwt无状态 或 token有状态的安全校验.
  • 代码生成:在线生成代码,并一键导入菜单到业务模块.
  • 导出excel文件 tealeg/xlsx.
  • api文档生成 swaggo/swag.
  • 图形验证码 base64Captcha.
  • 服务器监控 gopsutil.
  • 若依前端组件 RuoYi v4.7.0 .

内置功能

  1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
  2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
  3. 岗位管理:配置系统用户所属担任职务。
  4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
  5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
  6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
  7. 参数管理:对系统动态配置常用参数。
  8. 通知公告:系统通知公告信息发布维护。
  9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
  10. 登录日志:系统登录日志记录查询包含登录异常。
  11. 在线用户:当前系统中活跃用户状态监控。
  12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
  13. 代码生成:前后端代码的生成(Go、html、json、sql) 。
  14. 系统接口:根据业务代码自动生成相关的api接口文档。
  15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
  16. 在线构建器:拖动表单元素生成相应的HTML代码。
  17. 案例演示:常用的前端组件整合演示。

目录结构

本着简单易用的原则,简化工程结构。

main[]()     
├── bak               // 资料备份
│   └── local         // 本地配置文件备份
│   └── script        // 发布相关的脚本备份
│   └── sql           // 数据库文件备份
│   └── build.sh                 // 编译脚本,方便打包
│   └── build-cgo.sh             // 编译脚本,启用cgo,需要打包sqlite时有用
│   └── build-linux.bat          // 编译脚本,windows环境交叉编译用
│   └── data.db                  // 使用sqlite数据库时有用,只使用mysql可删除                             
├── modules                          // 模块存放目录
│   └── common                       // 通用模块
│   └── demo                         // 示例模块
│   └── things                       // 物联业务网模块
│   └── system                       // 系统核心模块
│       └── internal                 // 源码存放目录,internal禁止其它模块引用
│       └── static                   // 静态文件目录
│       └── mapper                   // 类mybatis映射文件存放目录
│       └── template                 // 模板存放目录
│       └── bootstrap.yml            // 项目根配置文件,模仿springboot
│       └── application.yml           // 项目配置文件,模仿springboot
├── pkg                              // 第三方开源组件存放目录
│    └── lv_framework                 // 框架通用模块
│          └── lv_cache              // 通用缓存
│          └── lv_conf               // 通用配置
│          └── lv_db                 // 数据库相关
│          └── lv_log                // 通用日志处理,统一风格,方便切换第三方日志库
│          └── utils                 // 通用工具类
│          └── web                   // 通用web组件
│       
├── go.work            // 项目模块配置
├── build-linux.bat    // 编译脚本
├── Dockerfile         // Docker镜像文件
├── main.go            // 程序入口文件

启动

前置条件:

  1. 配置GO_PROXY环境变量,如:export GO_PROXY=https://goproxy.cn 安装相关依赖!

1. 修改应该的数据库及缓存配置

  • sqlite:默认使用sqlite数据库,可不做任何修改
  • mysql: 导入docs中的sql文件,修改application.yml中的mysql相关信息

2. cd 进入main目录启动应用

  • 方式一 :常规启动
go run main.go

启动完成后,在控制台会打印出访问地址: http://127.0.0.1:8080

  • 方式二: 使用第三方热加载组件

前置条件: cd 到 main 目录,安装热加载框架:
go get github.com/pilu/fresh
go install github.com/pilu/fresh

启动

fresh

登录账号和密码

演示1: http://demo.lostvip.com

账号: admin / admin123

注意,本站未做任何防护,管理员有所有权限,请不要删除任何数据!

交叉编译

docker pull techknowlogick/xgo 交叉编译工具推荐使用xgo

# 全平台编译:
xgo -ldflags "-w -s"
# arm7平台:  
xgo -ldflags "-w -s"  -out svc-$(date '+%Y%m%d_%H%M%S') --targets=linux/arm-7 .

演示图

感谢(排名不分先后)

GORM https://gorm.io/ Tealeg https://github.com/tealeg/xlsx Swaggo https://github.com/swaggo/swag WEB框架 https://github.com/gin-gonic/gin 缓存框架 https://github.com/redis/go-redis 若依yjgo https://github.com/guolingege/yjgo RuoYi https://github.com/yangzongzhuan/RuoYi SQL文件解析: https://github.com/qustavo/dotsql 热加载框架 http://github.com/pilu/fresh 规则引擎 https://github.com/dop251/goja

项目前后端分离版

交流社区

交流社区

微信公众号 lostvip666 QQ群 43862272
微信公众号二维码 QQ群二维码

评论

暂无评论