当前位置: 首页 > news >正文

gorm sqlexpression如何公用

我来为你介绍 GORM 中 SQL Expression 的公用方式让你能复用复杂的 SQL 表达式逻辑。核心方式使用 gorm.Expr 自定义函数GORM 的 Expr 方法允许你构建可复用的 SQL 表达式。1. 基础封装通用表达式函数package exprimport (fmtgorm.io/gorm)// 通用表达式构建器type SQLExpr struct {SQL stringVars []interface{}}func (e SQLExpr) Expression() string {return e.SQL}// 可复用的表达式函数 // DateEqual 日期相等处理时区/格式问题func DateEqual(column string, date string) *gorm.SqlExpr {return gorm.Expr(DATE(?) ?, gorm.Expr(column), date)}// JSONExtract JSON字段提取func JSONExtract(column, path string) *gorm.SqlExpr {return gorm.Expr(JSON_UNQUOTE(JSON_EXTRACT(?, ?)), gorm.Expr(column), path)}// Coalesce 空值处理func Coalesce(columns ...string) *gorm.SqlExpr {if len(columns) 0 {return nil}sql : COALESCE( columns[0]for i : 1; i len(columns); i {sql , columns[i]}sql )return gorm.Expr(sql)}// IfNull NULL值替换func IfNull(column string, defaultVal interface{}) *gorm.SqlExpr {return gorm.Expr(IFNULL(?, ?), gorm.Expr(column), defaultVal)}// Round 四舍五入func Round(column string, decimals int) *gorm.SqlExpr {return gorm.Expr(ROUND(?, ?), gorm.Expr(column), decimals)}// Concat 字符串拼接func Concat(columns ...string) *gorm.SqlExpr {sql : CONCAT(for i, col : range columns {if i 0 {sql , }sql ?}sql )exprs : make([]interface{}, len(columns))for i, col : range columns {exprs[i] gorm.Expr(col)}return gorm.Expr(sql, exprs...)}// AgeFromBirthday 根据生日计算年龄func AgeFromBirthday(birthdayCol string) *gorm.SqlExpr {return gorm.Expr(TIMESTAMPDIFF(YEAR, ?, CURDATE()),gorm.Expr(birthdayCol),)}// FullTextSearch 全文搜索MySQLfunc FullTextSearch(columns []string, keyword string) *gorm.SqlExpr {cols : for i, c : range columns {if i 0 {cols , }cols c}return gorm.Expr(fmt.Sprintf(MATCH(%s) AGAINST (? IN BOOLEAN MODE), cols),keyword,)}2. 使用方式package mainimport (expr // 上面定义的包gorm.io/gorm)type User struct {ID uintName stringBirthday *time.TimeProfile string gorm:type:jsonScore float64BackupName string}// 在查询中复用 // 查询计算年龄var users []struct {UserAge int}db.Model(User{}).Select(*, ?, expr.AgeFromBirthday(birthday)).Scan(users)// 查询JSON提取 空值处理db.Model(User{}).Where(? ?, expr.JSONExtract(profile, $.city), 北京).Find(users)// 查询使用Coalescedb.Model(User{}).Select(id, ? as display_name, expr.Coalesce(name, backup_name, 未知)).Find(users)// 查询分数四舍五入db.Model(User{}).Select(id, ? as rounded_score, expr.Round(score, 2)).Find(users)// 查询全文搜索db.Model(User{}).Where(? 0, expr.FullTextSearch([]string{name, profile}, gorm)).Find(users)3. 高级封装Scope 模式最推荐使用 GORM 的 Scopes 实现链式复用package scopesimport (gorm.io/gormyourapp/expr)// 可复用的 Scope 函数// WithAge 添加年龄计算字段func WithAge() func(db *gorm.DB) *gorm.DB {return func(db *gorm.DB) *gorm.DB {return db.Select(*, ? as age, expr.AgeFromBirthday(birthday))}}// WithDisplayName 添加显示名称处理空值func WithDisplayName() func(db *gorm.DB) *gorm.DB {return func(db *gorm.DB) *gorm.DB {return db.Select(*, ? as display_name,expr.Coalesce(name, backup_name),)}}// WhereCity 按城市筛选JSON字段func WhereCity(city string) func(db *gorm.DB) *gorm.DB {return func(db *gorm.DB) *gorm.DB {return db.Where(? ?, expr.JSONExtract(profile, $.city), city)}}// WhereActive 筛选活跃用户综合条件func WhereActive() func(db *gorm.DB) *gorm.DB {return func(db *gorm.DB) *gorm.DB {return db.Where(last_login_at DATE_SUB(NOW(), INTERVAL 30 DAY))}}// OrderByScore 按分数排序处理NULLfunc OrderByScore(desc bool) func(db *gorm.DB) *gorm.DB {return func(db *gorm.DB) *gorm.DB {order : ASCif desc {order DESC}return db.Order(gorm.Expr(? order, expr.Coalesce(score, 0)))}}使用 Scope// 链式组合高度复用db.Model(User{}).Scopes(scopes.WithAge(),scopes.WithDisplayName(),scopes.WhereCity(北京),scopes.WhereActive(),scopes.OrderByScore(true),).Find(users)// 也可以单独使用db.Model(User{}).Scopes(scopes.WithAge()).Find(users)4. 复杂表达式子查询封装package expr// SubQueryExpr 子查询表达式type SubQueryExpr struct {DB *gorm.DBAlias string}func (s SubQueryExpr) Expression() string {return fmt.Sprintf((%s) as %s, s.DB.ToSQL(func(db *gorm.DB) *gorm.DB {return db}), s.Alias)}// AvgScoreByGroup 分组平均分子查询func AvgScoreByGroup(groupCol string) *gorm.DB {return db.Model(User{}).Select(groupCol, AVG(score) as avg_score).Group(groupCol)}// RankByScore 分数排名子查询func RankByScore() *gorm.DB {return db.Model(User{}).Select(id, RANK() OVER (ORDER BY score DESC) as rank)}5. 完整实战示例package mainimport (gorm.io/gormyourapp/expryourapp/scopes)// 业务场景获取用户列表包含计算字段支持筛选和排序func GetUserList(ctx context.Context, req UserListReq) ([]UserDTO, error) {var result []UserDTOquery : db.Model(User{}).Scopes(scopes.WithAge(), // 复用计算年龄scopes.WithDisplayName(), // 复用显示名称)// 动态条件if req.City ! {query query.Scopes(scopes.WhereCity(req.City))}if req.ActiveOnly {query query.Scopes(scopes.WhereActive())}// 排序switch req.SortBy {case score:query query.Scopes(scopes.OrderByScore(req.Desc))case age:query query.Order(expr.AgeFromBirthday(birthday))}err : query.Find(result).Errorreturn result, err}总结对比方式 适用场景 复用级别expr 函数包 简单SQL表达式 表达式级Scopes 模式 完整的查询条件/字段 查询片段级子查询封装 复杂统计/排名 查询块级推荐实践将常用的表达式抽到 expr 包将完整的查询逻辑抽到 scopes 包这样可以在不同业务模块中灵活组合复用。
http://www.gsyq.cn/news/1344850.html

相关文章:

  • 2026年天津黄金回收平台,福昌夏凭实力脱颖而出 - 黄金上门回收
  • RPG Maker MV/MZ游戏资源解密技术解析与实战指南
  • 08-前后端分离改造-把Chatchat嵌入你的业务系统
  • 5分钟快速上手:Scarab空洞骑士模组管理器完整使用指南
  • 实时API数据集成:从Yelp API到Postgres数据库的完整ETL流程
  • 从数据到图形:ElGrapho数据模型与布局算法深度解析
  • 从创意到分镜:用DeepSeek打造短视频一气呵成的秘密
  • REFramework游戏启动崩溃:如何高效解决注入冲突的实用解决方案
  • Closures vs BlocksKit:Swift与Objective-C闭包框架终极对比分析
  • Stylis构建与打包:从源码到生产环境的完整部署指南
  • 轻量级CSS预处理器Stylis:10分钟快速入门指南
  • Windows系统Btrfs驱动终极指南:免费解锁Linux文件系统的强大功能
  • 新疆市省心水电暖网络一站式:水磨沟专业的水电安装公司有哪些 - LYL仔仔
  • 3步解决微信红包难题:智能助手帮你告别手慢烦恼
  • CANN/asc-devkit矩阵计算优化实践
  • MOOTDX:Python量化投资的数据获取革命
  • 智能停车系统告别拥堵!巨有科技让景区停车畅行无忧
  • 泗阳县黄金回收哪家强?铭润稳居第一 - 亦辰小黄鸭
  • 掌握vim-mode的三种核心模式:Normal、Insert与Visual模式全解析
  • 鸣潮自动化终极指南:5步实现后台智能挂机,解放你的游戏时间
  • 探索Fluxxor生态系统:全面指南工具、插件与社区资源
  • 如何高效管理原神祈愿数据:genshin-wish-export完整使用指南
  • 中兴光猫工厂模式终极解锁工具:zteOnu完整指南
  • Warcraft Helper:让经典魔兽争霸3在现代系统高效运行的智能解决方案
  • 嵩县黄金回收哪家强?铭润稳居第一 - 亦辰小黄鸭
  • FFXVIFix终极指南:3分钟解锁《最终幻想16》超宽屏与帧率限制
  • Sixpack企业级A/B测试框架:知名公司如何用Sixpack优化产品决策的完整指南
  • CPU-X硬件检测工具:3步解决你90%的硬件识别难题
  • Findroid终极指南:如何打造您的Android私人影院
  • SMUDebugTool终极指南:5个高级技巧彻底解决AMD Ryzen系统性能问题