gorm-plus 多租户方案
gorm-plus 多租户方案企业级最佳实践一套真正适用于生产环境的 GORM 多租户解决方案对标 MyBatis-Plus多插件协同零侵入业务代码。连接地址✨ 为什么需要多租户在企业系统中常见场景SaaS 平台不同企业数据隔离多门店 / 多组织系统平台级业务用户数据隔离 核心问题只有一个如何做到数据隔离同时不侵入业务代码 gorm-plus 的解决方案gorm-plus 提供✅ 自动注入tenant_id✅ 支持查询 / 更新 / 删除 / 新增✅ 支持表级忽略✅ 支持超级管理员绕过✅ 支持数据权限插件叠加完全不需要手动写 WHERE tenant_id ? 核心设计1️⃣ 基于 GORM Callback 机制在以下阶段自动注入条件QueryUpdateDeleteCreate自动填充 tenant_id2️⃣ 插件责任链TenantPlugin → DataPermissionPlugin → AutoOperatorPlugin 多插件组合能力叠加不互相污染⚙️ 快速开始1️⃣ 初始化插件db.Use(tenant.New(tenant.Config{Enable:true,Column:tenant_id,IgnoreTables:[]string{sys_config,sys_dict,},SuperAdminBypass:true,}))2️⃣ 设置租户上下文ctx:tenant.SetTenantID(context.Background(),1001)dbdb.WithContext(ctx)3️⃣ 正常写业务代码无需改动db.Find(users) 实际执行 SQLSELECT*FROMusersWHEREtenant_id1001; 自动注入效果操作自动行为SELECT自动追加 tenant_idUPDATE自动限制 tenant_idDELETE自动限制 tenant_idINSERT自动填充 tenant_id 示例查询db.Where(name ?,张三).Find(list) 实际 SQLSELECT*FROMuserWHEREname张三ANDtenant_id1001;更新db.Model(User{}).Where(id ?,1).Update(name,李四) 实际 SQLUPDATEuserSETname李四WHEREid1ANDtenant_id1001;插入db.Create(User{Name:王五}) 实际 SQLINSERTINTOuser(name,tenant_id)VALUES(王五,1001); 忽略租户控制方式 1表级忽略IgnoreTables:[]string{sys_config,}方式 2临时关闭db.WithoutTenant().Find(list)方式 3超级管理员ctx:tenant.SetIsSuperAdmin(ctx,true) 自动跳过 tenant 过滤 JOIN 场景重点gorm-plus 自动处理SELECT*FROMorders oLEFTJOINusers uONo.user_idu.id 自动变成WHEREo.tenant_id1001ANDu.tenant_id1001防止跨租户数据泄露非常关键 与数据权限叠加可以同时使用db.WithContext(tenant.SetTenantID(ctx,1001),).WithDataScope(...) 最终 SQLWHEREtenant_id1001ANDdept_idIN(...)⚡ 性能优化gorm-plus 在多租户设计中✅ 避免重复注入✅ 使用 GORM schema 缓存✅ 最小侵入 SQL 构建✅ 插件链顺序可控 性能接近原生 GORM 最佳实践✅ 1. 所有表必须有 tenant_idtenant_idBIGINTNOTNULL✅ 2. 建立联合索引INDEXidx_tenant_id(tenant_id)或INDEXidx_tenant_user(tenant_id,user_id)✅ 3. 中间件统一注入funcTenantMiddleware()gin.HandlerFunc{returnfunc(c*gin.Context){tenantID:getTenantFromToken(c)ctx:tenant.SetTenantID(c.Request.Context(),tenantID)c.Requestc.Request.WithContext(ctx)c.Next()}} 总结gorm-plus 多租户方案用最少的侵入实现最安全的数据隔离