分享 golang 一种快捷自动实现查询条件构建的思路

2023-03-07 21:23:22 +08:00
 8520ccc

之前的方案

我之前的方案就是给每个需要查询的字段加到请求的 struct 中,然后在请求时判断是否为空,不为空时则加入到查询条件

type TransferFetchReq struct {
	g.Meta `path:"/transfer/fetch" method:"post" sm:"列表转账" tags:"转账"`
	types.PageReq
	UserID int64                `json:"user_id" dc:"用户 ID"`
}

//在控制器中加入

if req.UserID != 0 {
		u = u.Where("user_id = ?", req.UserID)
}

但是这样的方案需要给每个条件写一份代码,太耗时间了

新的方案

把时间拿去写 struct 即可,如下:

type TransferFetchFilter struct {
	ID         int64   `json:"id"`
	CreatedAt  []int64 `json:"created_at" cond:"between" dc:"创建时间"`
	UpdatedAt  []int64 `json:"updated_at" cond:"between" dc:"更新时间"`
	FromID     int64   `json:"from_id" dc:"转出用户 ID"`
	DestID     int64   `json:"dest_id" dc:"转入用户 ID"`
	Code       string  `json:"code"`
	Type       []uint  `json:"type" cond:"in"`
	State      []uint  `json:"state" cond:"in"`
}

如上,只需要写好这样的 struct ,即可完成所有字段的查询,可以通过 cond 指定查询方法 例如 LIKE/EQ/IN/NOTIN/between 等....

当然,前提是必须把对应的数据类型写对(否则不会生效)

例如查询方案为:IN 时 则数据类型必须是 []xxx

默认为 EQ 即等于 则不能是 slice 默认查询字段取 json tag 当然还可以有一个更高优先级的 tag 例如 bind 这样可以同时对一个字段提供多种查询方法 这样就方便多了....................

1418 次点击
所在节点    Go 编程语言
14 条回复
lesismal
2023-03-08 00:25:50 +08:00
ORM 没什么好的,试试我这个丫:
https://github.com/lesismal/sqlw
8520ccc
2023-03-08 00:34:50 +08:00
@lesismal 你这个太折磨人了

我不手写 sql 的
一是不太会写,二是怕有注入漏洞

目前 ORM 用的挺爽
lesismal
2023-03-08 02:42:08 +08:00
之前在其他帖子也聊过,其实基础知识部分而言,学习 sql 本身并不比学习 orm 需要更多时间,而且逐渐积累起来,你对项目的掌控能力更强,尤其是性能相关,这是对于做大一些的项目的一些核心能力、涨工资或者说进阶的必备知识。一开始便依赖 orm ,并且不求深究,相当于自断了技术进阶的道路。
当然,比如家里条件比较好、只是给自己定位 curd 中小项目,追求的是 work life balance and happiness ,那就无所谓了、orm 挺好
8520ccc
2023-03-08 08:58:08 +08:00
@lesismal I don’t care 我不上班,都是自己做事情的
zmqiang
2023-03-08 10:47:16 +08:00
@lesismal 你这项目蛮有意思的,我来看一看
thinkingbullet
2023-03-08 10:55:07 +08:00
gorm?另外我觉的 between 查询 应该写成 CreatedAt [2]int64, 限定是数组,必须有两个元素
lesismal
2023-03-08 10:57:58 +08:00
@8520ccc #4 那就无所谓了,自己用着舒服就是最好的
@zmqiang 欢迎使用!
8520ccc
2023-03-08 11:54:06 +08:00
@thinkingbullet 不限定,到时候自动判定入参个数截取即可
8520ccc
2023-03-08 11:56:40 +08:00
@lesismal 嗯嗯,我目前是以开发效率为前提的

性能暂时不考虑(因为前期根本不存在性能问题)

真的出现性能问题,再优化也来得及
ace12
2023-03-08 14:20:13 +08:00
8520ccc
2023-03-09 00:28:16 +08:00
@ace12 思路差不多,不过我没做 or 这些,因为我前端查询不需要 OR 这个
thinkingbullet
2023-03-09 10:28:17 +08:00
@ace12 你这里有这样一句话 "当值为 0 值或空值或者 op tag 值为"-"会跳过" 那我必须要查为 0 值或为空值怎么办呢,比如 where status=0
ace12
2023-03-10 14:54:38 +08:00
@thinkingbullet 之前还真没有考虑 null 的查询 现在加上啦

```go
type UserWhere8 struct {
DeletedAt bool `op:"null"` //为 true 时查询 IS NULL 为 false 时跳过条件
Status *int
CreatedAt *bool `op:"null"` //为 true 时查询 IS NULL ,为 false 时查询 IS NOT NULL
}
var status int
var created bool
u9 := UserWhere8{
DeletedAt: true,
Status: &status,
CreatedAt: &created,
}

var user []User
//SELECT * FROM `user` WHERE deleted_at IS NULL AND status = 0 AND created_at IS NOT NULL
DB.Scopes(structquery.Where(u9)).Find(&user)
```
thinkingbullet
2023-03-12 10:27:21 +08:00
@ace12 nice 果断 star

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/922028

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX