V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
8520ccc
V2EX  ›  Go 编程语言

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

  •  1
     
  •   8520ccc · 2023-03-07 21:23:22 +08:00 · 1405 次点击
    这是一个创建于 634 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前的方案

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

    14 条回复    2023-03-12 10:27:21 +08:00
    lesismal
        1
    lesismal  
       2023-03-08 00:25:50 +08:00
    ORM 没什么好的,试试我这个丫:
    https://github.com/lesismal/sqlw
    8520ccc
        2
    8520ccc  
    OP
       2023-03-08 00:34:50 +08:00 via iPhone
    @lesismal 你这个太折磨人了

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

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

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

    真的出现性能问题,再优化也来得及
    ace12
        10
    ace12  
       2023-03-08 14:20:13 +08:00
    8520ccc
        11
    8520ccc  
    OP
       2023-03-09 00:28:16 +08:00 via iPhone
    @ace12 思路差不多,不过我没做 or 这些,因为我前端查询不需要 OR 这个
    thinkingbullet
        12
    thinkingbullet  
       2023-03-09 10:28:17 +08:00
    @ace12 你这里有这样一句话 "当值为 0 值或空值或者 op tag 值为"-"会跳过" 那我必须要查为 0 值或为空值怎么办呢,比如 where status=0
    ace12
        13
    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
        14
    thinkingbullet  
       2023-03-12 10:27:21 +08:00
    @ace12 nice 果断 star
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   932 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 21:48 · PVG 05:48 · LAX 13:48 · JFK 16:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.