The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
8520ccc

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

  •  1
     
  •   8520ccc · Mar 7, 2023 · 2057 views
    This topic created in 1187 days ago, the information mentioned may be changed or developed.

    之前的方案

    我之前的方案就是给每个需要查询的字段加到请求的 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 replies    2023-03-12 10:27:21 +08:00
    lesismal
        1
    lesismal  
       Mar 8, 2023
    ORM 没什么好的,试试我这个丫:
    https://github.com/lesismal/sqlw
    8520ccc
        2
    8520ccc  
    OP
       Mar 8, 2023 via iPhone
    @lesismal 你这个太折磨人了

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

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

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

    真的出现性能问题,再优化也来得及
    ace12
        10
    ace12  
       Mar 8, 2023
    8520ccc
        11
    8520ccc  
    OP
       Mar 9, 2023 via iPhone
    @ace12 思路差不多,不过我没做 or 这些,因为我前端查询不需要 OR 这个
    thinkingbullet
        12
    thinkingbullet  
       Mar 9, 2023
    @ace12 你这里有这样一句话 "当值为 0 值或空值或者 op tag 值为"-"会跳过" 那我必须要查为 0 值或为空值怎么办呢,比如 where status=0
    ace12
        13
    ace12  
       Mar 10, 2023
    @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  
       Mar 12, 2023
    @ace12 nice 果断 star
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3007 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 53ms · UTC 07:13 · PVG 15:13 · LAX 00:13 · JFK 03:13
    ♥ Do have faith in what you're doing.