Golang Go语言中分享一种快捷自动实现查询条件构建的思路

之前的方案

我之前的方案就是给每个需要查询的字段加到请求的 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 这样可以同时对一个字段提供多种查询方法 这样就方便多了....................


Golang Go语言中分享一种快捷自动实现查询条件构建的思路

更多关于Golang Go语言中分享一种快捷自动实现查询条件构建的思路的实战教程也可以访问 https://www.itying.com/category-94-b0.html

15 回复

ORM 没什么好的,试试我这个丫:
https://github.com/lesismal/sqlw

更多关于Golang Go语言中分享一种快捷自动实现查询条件构建的思路的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你这个太折磨人了

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

目前 ORM 用的挺爽

之前在其他帖子也聊过,其实基础知识部分而言,学习 sql 本身并不比学习 orm 需要更多时间,而且逐渐积累起来,你对项目的掌控能力更强,尤其是性能相关,这是对于做大一些的项目的一些核心能力、涨工资或者说进阶的必备知识。一开始便依赖 orm ,并且不求深究,相当于自断了技术进阶的道路。
当然,比如家里条件比较好、只是给自己定位 curd 中小项目,追求的是 work life balance and happiness ,那就无所谓了、orm 挺好

I don’t care 我不上班,都是自己做事情的

你这项目蛮有意思的,我来看一看

gorm?另外我觉的 between 查询 应该写成 CreatedAt [2]int64, 限定是数组,必须有两个元素

#4 那就无所谓了,自己用着舒服就是最好的
欢迎使用!

不限定,到时候自动判定入参个数截取即可

嗯嗯,我目前是以开发效率为前提的

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

真的出现性能问题,再优化也来得及

思路差不多,不过我没做 or 这些,因为我前端查询不需要 OR 这个

你这里有这样一句话 “当值为 0 值或空值或者 op tag 值为”-“会跳过” 那我必须要查为 0 值或为空值怎么办呢,比如 where status=0

之前还真没有考虑 null 的查询 现在加上啦

go<br>type UserWhere8 struct {<br> DeletedAt bool `op:"null"` //为 true 时查询 IS NULL 为 false 时跳过条件<br> Status *int<br> CreatedAt *bool `op:"null"` //为 true 时查询 IS NULL ,为 false 时查询 IS NOT NULL<br>}<br>var status int<br>var created bool<br>u9 := UserWhere8{<br> DeletedAt: true,<br> Status: &amp;status,<br> CreatedAt: &amp;created,<br>}<br><br>var user []User<br>//SELECT * FROM `user` WHERE deleted_at IS NULL AND status = 0 AND created_at IS NOT NULL<br>DB.Scopes(structquery.Where(u9)).Find(&amp;user)<br>

nice 果断 star

在Golang中,实现快捷自动构建查询条件是一个常见需求,特别是在处理动态查询参数时。以下是一种高效且灵活的思路,利用结构体标签和反射机制来自动构建查询条件:

  1. 定义结构体与标签: 首先,定义一个包含查询字段的结构体,并为每个字段添加自定义标签,如db:"column_name",用于指定数据库中的列名。还可以添加其他标签来控制查询条件的行为,如是否忽略空值等。

  2. 反射解析结构体: 使用反射包(reflect)来遍历结构体的字段,读取标签信息,并根据字段值构建查询条件。对于非空字段,生成相应的SQL条件片段,如column_name = ?,并收集字段值以供后续执行查询时使用。

  3. 条件拼接与执行: 将所有生成的查询条件片段使用逻辑运算符(如AND)拼接起来,形成完整的查询语句。然后,使用数据库驱动执行该查询,传入之前收集的字段值作为参数。

  4. 优化与扩展: 可以进一步优化此方法,如支持更复杂的查询逻辑(OR条件、范围查询等),以及集成到ORM框架中以减少重复代码。此外,通过缓存查询计划或预编译语句,可以提高查询性能。

这种方法的好处在于,它提供了一种灵活且可维护的方式来构建动态查询条件,无需手动编写大量的条件判断代码。同时,利用结构体标签和反射机制,使得代码更加清晰和易于理解。

回到顶部