go-zero 成长之路—微服务电商实战系列(六、条件查询)
该系列源码已开源:micro-shop
1. 概述
在产品服务版块
中咱们会有分页和条件的检索查询
对应的产品列表。
所以咱们这边讲一下在开发过程中会出现的一些清情况:
- 检索条件的组合
- 分页条数的计算
- 检索条件的
sql
语句格式化输出 - 数据的返回
这里总共3
个情况。
如果历史文章不是很清楚的,可通过如下传送门查看该系列其他文章:
- go-zero 成长之路—微服务电商实战系列(五、RPC定义)
- go-zero 成长之路—微服务电商实战系列(四、API定义)
- go-zero 成长之路—微服务电商实战系列(三、表结构篇)
- go-zero 成长之路—微服务电商实战系列(二、划分篇)
- go-zero 成长之路—微服务电商实战系列(一、需求篇)
2. 检索条件的组合
这里我列举了产品列表常用的检索条件:
- 页码:
int64
- 每页条数:
int64
- 产品名称:
模糊查询 [position('搜索字符' in 字段)]
- 产品状态:
int64 [0,1,2,3]
- 产品添加时间:
时间段
检索条件组合
具体代码如下:
Search := "1 = 1"
// 产品名称
if len(req.ProductName) > 0 {
Search = Search + fmt.Sprintf(" AND position('%s' in `title`)", req.ProductName)
}
// 产品状态 0,1,2,3
if req.State > 0 {
Search = Search + fmt.Sprintf(" AND state = %d", req.State)
}
// 产品添加时间 开始-结束
if len(req.SearchTime) > 0 {
Search = Search + fmt.Sprintf(" AND create_time between '%s' AND '%s'", req.SearchTime, req.SearchTime)
}
注意:产品添加时间时间段,这里最好使用:
between ... and ...
分页条数的计算
mysql
中的limit
是用来分页查询的。
limit
有两个参数:起始偏移量
、查询条数
- 起始偏移量:
offset
- 查询条数:
pageSize
- 计算方式:
(当前页数 - 1) x 查询条数 = 偏移量
具体代码如下:
// Page 已知,PageSize 已知
// 计算方式:(当前页数 - 1) x 查询条数 = 偏移量
offset := (Page - 1) * PageSize
检索条件的sql
语句格式化输出
这里分为两种情况:
- 没有检索条件:只有
Page
、PageSize
- 有检索条件
具体代码如下:
// 声明错误
var err error
// 分页使用的偏移量
offset := (Page - 1) * PageSize
if len(where) == 0 {
// 没有检索条件:只有 `Page` 、`PageSize`
query := fmt.Sprintf("select %s from %s order by create_time desc limit ?,?", productRows, m.table)
err = m.conn.QueryRowsCtx(ctx, &resp, query, offset, PageSize)
} else {
// 有检索条件
query := fmt.Sprintf("select %s from %s where %s order by create_time desc limit ?,?", productRows, m.table, where)
err = m.conn.QueryRowsCtx(ctx, &resp, query, offset, PageSize)
}
注意:如果检索条件使用
>=
、<=
在格式化输出并执行sql
时,会出现>=
和<=
转义成实体字符,无法进行得到正常的sql语句查询的结果
完整的代码
具体代码如下:
func (m *defaultProductModel) FindPaginations(ctx context.Context, where string, Page, PageSize int64) ([]Product, error) {
var resp []Product
var err error
offset := (Page - 1) * PageSize
if len(where) == 0 {
query := fmt.Sprintf("select %s from %s order by create_time desc limit ?,?", productRows, m.table)
err = m.conn.QueryRowsCtx(ctx, &resp, query, offset, PageSize)
} else {
query := fmt.Sprintf("select %s from %s where %s order by create_time desc limit ?,?", productRows, m.table, where)
err = m.conn.QueryRowsCtx(ctx, &resp, query, offset, PageSize)
}
switch err {
case nil:
return resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
3. 结束语
本篇文章介绍说明了在开发过程中会出现的一些清情况:
- 检索条件的组合
- 分页条数的计算
- 检索条件的
sql
语句格式化输出 - 数据的返回
另外,如果你感兴趣,非常欢迎你加入,我们一起来完成这个项目,为社区献出自己的一份力。
希望本篇文章对你有所帮助,谢谢。