文章目录

前言

书接上回,解决了选择性的忽略某些字段这个问题,新的问题出现,想要使用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中的一小部分,以后用到别的部分自己也会分享出来,如有错误,望大佬指正。
在这里插入图片描述

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐