前言 越高级,越复杂的查询,也同时意味着高耗,但是平时有一些数据少,但是业务复杂的场景,可以使用下。这里主要说明的是go中使用gorm进务查询。gormimport依赖databasesqlfmtgithub。comjinzhugormgithub。comjinzhugormdialectsmysql将查询结果放到一个struct中根据主键查询第一条记录db。First(user)SELECTFROMusersORDERBYidLIMIT1;随机获取一条记录db。Take(user)SELECTFROMusersLIMIT1;根据主键查询最后一条记录db。Last(user)SELECTFROMusersORDERBYidDESCLIMIT1;查询所有的记录db。Find(users)SELECTFROM查询指定的某条记录(仅当主键为整型时可用)db。First(user,10)SELECTFROMusersWHEREid10;查询条件是map或者struct查询 有时候代码是可需要映射到一个map结构,不需要映射到一个结构体中,可以写成如下:forupdate 在涉及并发的场景,往往需要加锁互斥,和Java类似,Go中也有加行锁的方式,加forupdate即可。 一般写法如下:为查询SQL添加额外的SQL操作db。Set(gorm:queryoption,FORUPDATE)。First(user,10)SELECTFROMusersWHEREid10FORUPDATE; 示例代码:err:db。Model(XXX{})。Set(gorm:queryoption,FORUPDATE)。Where(XXX?,XXX)。First(XXX)。Erroriferr!nil{iferrgorm。ErrRecordNotFound{logs。Warn(xxx)returnnil,nil}logs。Error(XXX)}Count查询 有时候,我们需要进行简单的数据统计,比如查询到结果有多少行,varcountint64db。Model(User{})。Where(name?,jinzhu)。Or(name?,jinzhu2)。Count(count)SELECTcount()FROMusersWHEREnamejinzhuORnamejinzhu2db。Model(User{})。Where(name?,jinzhu)。Count(count)SELECTcount()FROMusersWHERE(count)分组计数 有时候也需要分组统计行数分组计数users:〔〕User{{Name:name1},{Name:name2},{Name:name3},{Name:name3},}DB。Model(User{})。Group(name)。Count(count)count3去重统计去重计数DB。Model(User{})。Distinct(name)。Count(count)SELECTCOUNT(DISTINCT(name))FROMusersGroupHaving 有时候我们会使用到数据统计的功能,比如根据数据库字段batchno进行分组,然后统计总金额,总笔数。 分组查询统计一般的写法如下:db。Table(orders)。Select(date(createdat)asdate,sum(amount)astotal)。Group(date(createdat))。Having(sum(amount)?,100)。Scan(results) 代码示例:typeSumstruct{BatchNostringgorm:column:batchnojson:batchnoTotalCountsint64gorm:column:totalcountsjson:totalcountsTotalAmountsint64gorm:column:totalamountsjson:totalamounts}varresult〔〕Sumdb:db。Model(Voucher{})。Select(batchno,count(1)astotalCounts,sum(amount)astotalAmounts)status:〔〕string{10,20,40}dbdb。Where(no?,startVoucherNo)dbdb。Where(no?,endVoucherNo)dbdb。Where(batchnoIN?,batchNos)dbdb。Where(statusIN?,status)ifshardingKey0{dbdb。Where(shardingkey,shardingKey)}dbdb。Group(batchno)err:db。Scan(result)。Erroriferr!nil{iferrgorm。ErrRecordNotFound{logs。CtxWarn(xxx)returnnil,nil}logs。CtxError(ctx,xxx,err)}Join查询 一般来说,很少使用关联查询,但是如果要使用关联查询,可以如下:db。Table(users)。Select(users。name,emails。email)。Joins(leftjoinemailsonemails。useridusers。id)。Scan(results)多连接及参数db。Joins(JOINemailsONemails。useridusers。idANDemails。email?,jinzhuexample。org)。Joins(JOINcreditcardsONcreditcards。useridusers。id)。Where(creditcards。number?,411111111111)。Find(user)查询指定函数 Scopes允许你指定常用的查询,可以在调用方法时引用这些查询,也就是说,可以在查询中使用函数。 举个例子:funcAmountGreaterThan1000(dbgorm。DB)gorm。DB{returndb。Where(amount?,1000)}funcPaidWithCreditCard(dbgorm。DB)gorm。DB{returndb。Where(paymodesign?,C)}funcPaidWithCod(dbgorm。DB)gorm。DB{returndb。Where(paymodesign?,C)}db。Scopes(AmountGreaterThan1000,PaidWithCreditCard)。Find(orders)查找所有金额大于1000的信用卡订单db。Scopes(AmountGreaterThan1000,PaidWithCod)。Find(orders)查找所有金额大于1000的货到付款订单欢迎关注:程序员财富自由之路 在这里插入图片描述参考资料https:www。cnblogs。comzisefeizhup12788060。htmlhttps:gorm。iozhCNdocsadvancedquery。htmlhttps:www。bookstack。cnreadgorm2。0docsadvancedquery。md4abzu1