前言
书接上回,解决了选择性的忽略某些字段这个问题,新的问题出现,想要使用gorm完成动态sql,我只知道mybatis中使用标签可以完成动态sql,不会使用gorm完成动态sql,下面通过一个需求学习一下gorm的动态sql。
需求
要求实现功能:商品的字段为商品ID、商品名字、商品价格、商品介绍、商品分类,前端传来的数据为名字、介绍、分类,该三个字段均可能为空,根据前端传来的不为空的数据进行模糊查询,并将查询到的数据返回给前端。
实现步骤
1、先定义商品结构体和搜索请求结构体
type Commodity struct {
CommodityId int64 `json:"commodity_id" gorm:"not null;comment:'商品ID'"`
Name string `json:"name" gorm:"comment:'商品名'"`
Price float64 `json:"price" gorm:"comment:'价格'"`
Introduction string `json:"introduction" gorm:"comment:'商品简介'"`
Classify string `json:"classify" gorm:"comment:'分类'"`
}
type SearchCommodityReq struct {
Name string `json:"name" gorm:"omitempty;comment:'商品名'"`
Introduction string `json:"introduction" gorm:"omitempty;comment:'商品简介'"`
Classify string `json:"classify" gorm:"omitempty;comment:'分类'"`
}
2、route 层
com := r.Group("commodity")
{
com.GET("searchCommodityByQuery", controller.SearchCommodityByQuery) //通过名字、介绍、分类进行查询
}
3、controller 层
func SearchCommodityByQuery(c *gin.Context) {
// 查询到的商品不一定为1个,需要使用切片
var commodity []model.Commodity
var searchComReq model.SearchCommodityReq
if err := c.ShouldBindJSON(&searchComReq); err != nil {
zap.L().Error("SearchCommodityByQuery with param invalid,err:", zap.Error(err))
app.ResponseError(c, app.CodeInvalidParam)
return
}
commodity, err := service.SearchCommodityByQuery(searchComReq)
if err != nil {
zap.L().Error("service.SearchCommodityByQuery(searchComReq) is failed", zap.Error(err))
app.ResponseErrorWithMsg(c, err.Error())
return
}
c.JSON(http.StatusOK,commodity)
}
4、service 层
func SearchCommodityByQuery(req model.SearchCommodityReq) (commodity []model.Commodity, err error) {
if commodity, err = mysql.SearchCommodityByQuery(req); err != nil {
zap.L().Error("mysql.SearchCommodityByQuery(req) is failed", zap.Error(err))
return
}
return
}
5、mysql 层
func SearchCommodityByQuery(req model.SearchCommodityReq) (commodity []model.Commodity, err error) {
name := req.Name
introduction := req.Introduction
classify := req.Classify
query := global.GB_MDB.Model(&commodity)
if name != "" {
query = query.Where("name like ?", "%"+name+"%")
}
if introduction != "" {
query = query.Where("introduction like ?", "%"+introduction+"%")
}
if classify != "" {
query = query.Where("classify like ?", "%"+classify+"%")
}
err = query.Find(&commodity).Error
// 之前的思路写的代码
//err = global.GB_MDB.Model(&commodity).
// Where("name like ?", name).
// Or("introduction", introduction).
// Or("classify", classify).
// Find(&commodity).
// Error
return
}
我在 mysql 层摒弃之前使用的“得心应手”的链式编程,感觉自己故步自封了,太依赖于链式编程,使得思维固化了,使用拼接的方式进行查询数据恰好可以到达动态sql的查询。
这篇博客学习的动态sql 只是动态sql中的一小部分,以后用到别的部分自己也会分享出来,如有错误,望大佬指正。