后端CRUD提质增效:4个基类小优化,少踩坑少写代码
文章目录前言1. 90%后端都踩过的排序小坑1.1 分页数据重复大概率是它搞的鬼1.2 一行逻辑堵死这个坑2. 又省了N行代码封装BuildSerOpts方法2.1 以前的写法有多啰嗦2.2 封装完直接一行搞定3. 扩展性拉满自定义扩展参数解析器3.1 以前传自定义参数有多折腾3.2 新玩法想传啥就传啥4. 又少一个坑新增默认忽略主键4.1 一个经常忘写的小细节4.2 基类自动帮你处理P.S. 无意间发现了一个巨牛的人工智能教程非常通俗易懂对AI感兴趣的朋友强烈推荐去看看传送门https://blog.csdn.net/HHX_01前言做后端写CRUD写久了最大的成就感从来不是写了多少复杂业务而是给基类添上几个实用功能把重复代码干掉一大片。毕竟少写一行模板代码就多一分钟摸鱼时间这笔账怎么算都划算。1. 90%后端都踩过的排序小坑1.1 分页数据重复大概率是它搞的鬼说出来你可能不信我刚入行的时候一直以为数据库返回的数据默认就是按主键排好序的。直到有次线上分页出现重复数据我查了整整一下午最后被老大指着鼻子说“你连order by都不加”还真不是数据库坑你规矩就是这样只要你不写ORDER BY人家根本不保证返回顺序。先查到哪行就输出哪行跟食堂打饭不排队一样下一勺舀到谁全看大妈心情。平时单页看看好像没事一分页就炸锅。今天第二页和第一页重复两条明天又漏掉三条用户追着你提bug你对着代码查半天最后发现就是少写了俩单词。1.2 一行逻辑堵死这个坑解法其实很简单就两条规则用户传了排序字段就优先用用户的没传的话默认按主键排序。就算用户传了排序字段也得拿主键兜底。不然万一排序字段的值全一样比如一堆状态相同的数据又会回到随机排序的状态。相当于排队先按部门排部门一样就按工号排总不至于两个人工号也撞了吧。2. 又省了N行代码封装BuildSerOpts方法2.1 以前的写法有多啰嗦之前调用服务层方法每次都要手动拼一堆参数。就拿最简单的Get方法来说Omit字段、Select字段、主键值零零散散写一堆entity,err:h.svc.Get(c,service.Options{Omit:h.cfg.Omit.Get,Select:h.cfg.Select.Get,PrimaryKey:c.Param(pk),})这还只是单条查询列表接口参数更多写一次复制一次哪天要改个通用配置全项目搜着改改到眼睛发花。2.2 封装完直接一行搞定直接在基控制器里封个BuildSerOpts方法把通用配置都藏进去。改造之后同样的逻辑直接缩成这样opts:h.BuildSerOpts(c,Get,Request{PrimaryKeyValue:c.Param(pk),})entity,err:h.svc.Get(c,opts)不用再单独传Omit和Select列表接口收益更大原来七八行的参数拼装直接一行搞定。省下来的时间泡杯茶刷会儿帖子它不香吗。3. 扩展性拉满自定义扩展参数解析器3.1 以前传自定义参数有多折腾之前基类的参数都是固定死的Omit、Select、查询条件就那几样跟预制菜似的料都给你配好了想加勺辣椒都不行。万一业务要传点自定义的东西比如当前登录的管理员信息那麻烦可就大了。你得从控制器开始加参数传到服务层服务层加字段要是还要往下传仓储层也得改。一套流程走下来小半天没了头发还掉好几根。就像你只想给快递加个“放门口”的备注结果得从快递员、站点、分拨中心一层层打招呼纯纯的多此一举。3.2 新玩法想传啥就传啥思路很简单服务层的Options里加个Extension字段类型是any啥都能装。typeOptionsstruct{OmitFields[]stringSelectFields[]stringWheres[]Where SortFieldstringSortOrderstringPageintLimitintPrimaryKeyValuestringPrimaryKeyValues[]stringExtension any// 任意自定义扩展参数}控制器层更灵活直接传一个解析函数进去自己从上下文里拿数据组装好了扔给Extension。比如要传管理员会话先在服务层定义好扩展结构体typeAuthAdminRuleExtensionstruct{AdminSession*dto.AdminSession}初始化控制器的时候用WithExtension传个解析函数就行funcNewAuthAdminRuleHandler(svc*svcAuth.AuthAdminRuleService)*AuthAdminRuleHandler{returnAuthAdminRuleHandler{Handler:handler.NewHandler(svc,handler.WithExtension(func(c*gin.Context)any{returnsvcAuth.AuthAdminRuleExtension{AdminSession:middleware.GetAdmin(c),}}),),svc:svc,}}服务层用的时候直接断言取出来extension,ok:opts.Extension.(*AuthAdminRuleExtension)if!ok||extension.AdminSessionnil{returnnil,errors.New(参数错误缺少 AdminSession 扩展数据)}// 直接使用 extension.AdminSession底层基类一点不用动想传什么自定义参数自己定义就行自由度直接拉满。4. 又少一个坑新增默认忽略主键4.1 一个经常忘写的小细节我们之前有OmitFields配置可以指定新增时忽略哪些字段。但主键这东西新增的时候本来就不该手动传。总不能每次写接口都手动把主键加到忽略列表里吧新手写代码经常忘这事一运行就报错对着错误日志发呆半小时最后发现就是主键没忽略。4.2 基类自动帮你处理直接在基类里加个逻辑执行创建操作的时候如果没特意配置OmitFields默认就把主键字段给忽略掉。反正主键要么自增要么程序生成本来就不该前端传过来。基类直接帮你兜底又少一个踩坑的地方。基类优化就是这样都是些不起眼的小改动。但一点点攒下来写业务的时候就能少踩很多坑少写很多重复代码。做开发嘛能偷懒的地方一定要偷懒把精力留给真正值钱的业务逻辑。P.S. 无意间发现了一个巨牛的人工智能教程非常通俗易懂对AI感兴趣的朋友强烈推荐去看看传送门https://blog.csdn.net/HHX_01