go-gorm / gorm

The fantastic ORM library for Golang, aims to be developer friendly
https://gorm.io
MIT License
36.19k stars 3.88k forks source link

Could GORM support the freedom to choose whether to query zero fields when querying by struct? #5859

Open 2292384454 opened 1 year ago

2292384454 commented 1 year ago

Describe the feature

When querying with struct, the released GORM will only query with non-zero fields, that means if the field’s value is 0, '', false or other zero values, it won’t be used to build query conditions. And if I want to include zero values in the query conditions, I must use a map, which will include all key-values as query conditions. But it is obvious that querying with structure is simpler and more convenient than querying with map query(e.g. My field names may be modified, and I don't want to modify the map in every query statement). So could GORM to support the freedom to choose whether to query zero fields when querying by struct? And adding a parameter to let the user choose whether to query the zero fields, it is compatible with the existing query method.

Motivation

More simply, conveniently and uniformly to build query conditions.

Related Issues

kvii commented 1 year ago

You can use sql.NullXxx for your query.

package main

import (
    "database/sql"
    "fmt"

    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

type Query struct {
    A int
}

type NullableQuery struct {
    A sql.NullInt64 // <- You can use sql.NullXxx for your query.
}

func main() {
    db, err := gorm.Open(sqlite.Open(":memory"))
    if err != nil {
        panic(err)
    }

    {
        q := Query{
            A: 0, // It will occur a bug when you need zero-value conditions.
        }
        s := db.ToSQL(func(tx *gorm.DB) *gorm.DB {
            return tx.Table("m").Where(q).Find(&q)
        })
        fmt.Println(s)
        // SELECT * FROM `m`
    }
    {
        q := NullableQuery{
            A: sql.NullInt64{
                Int64: 0,
                Valid: true,
            },
        }
        s := db.ToSQL(func(tx *gorm.DB) *gorm.DB {
            return tx.Table("m").Where(q).Find(&q)
        })
        fmt.Println(s)
        // SELECT * FROM `m` WHERE `m`.`a` = 0
    }
    {
        q := NullableQuery{
            A: sql.NullInt64{
                Int64: 1,
                Valid: true,
            },
        }
        s := db.ToSQL(func(tx *gorm.DB) *gorm.DB {
            return tx.Table("m").Where(q).Find(&q)
        })
        fmt.Println(s)
        // SELECT * FROM `m` WHERE `m`.`a` = 1
    }
}