Gorm: 查询出来的数据能不能放到一个map里面? 用map做查询条件时对于slice都是当成字符串处理?

Created on 24 Aug 2018  ·  9Comments  ·  Source: go-gorm/gorm

func main() {
        resultMap := make(map[string]interface)
    db.Table("tableName").select("*").Scan(&resultMap)  //能不能提供这个功能将查询数据放入Map
//如果where里面的map有数组会被当成字符串处理
db.Where(map[string]interface{}{"name": "jinzhu", "age": {20,19,18}}).Find(&users)
//语句执行:select * from user where name='jinzhu' and age ='[20,19,18]'
//期望执行:select * from user where name='jinzhu' and age in (20,19,18)
}

Most helpful comment

This is the way I use SQL build.

func TestWhereBuild(t *testing.T) {
    cond, vals, err := whereBuild(map[string]interface{}{
        "name": "jinzhu", 
        "age in": []int{20, 19, 18},
    })
    if err != nil {
        t.Fatal(err)
    }
    t.Log(cond)
    t.Log(vals)

    db.Where(cond, vals...).Find(&users)

}

This is a method of use.

All 9 comments

Please use English so that more people can help you. You can use Google translate.

db.Where(map[string]interface{}{"name": "jinzhu", "age": {20,19,18}}).Find(&users)

This is a function. I realized a similar function by writing a SQL Build.

I know this can be done by writing SQL, but I think it's easier to put query parameters into the map, but if you put arrays in the map, you don't automatically use'in'to query, you use'='

My problem
func main() {
resultMap := make(map[string]interface)
db.Table("tableName").select("*").Scan(&resultMap) //Can you provide this function and put query //data in Map? if map in where has arrays, it will be treated as strings.
db.Where(map[string]interface{}{"name": "jinzhu", "age": {20,19,18}}).Find(&users)
//Statement execution:select * from user where name='jinzhu' and age ='[20,19,18]'
//Expected execution:select * from user where name='jinzhu' and age in (20,19,18)
}

@qianqianyeye You made a mistake. The parameters I passed were also maps. I wrote an SQL build at the top level to implement more powerful parameters and generate more flexible SQL statements.

I think you can do that.

If it is convenient for you, can you give me an example?

package model

import (
    "fmt"
    "strings"
)

type NullType byte

const (
    _ NullType = iota
    // IsNull the same as `is null`
    IsNull
    // IsNotNull the same as `is not null`
    IsNotNull
)

// sql build where
func whereBuild(where map[string]interface{}) (whereSQL string, vals []interface{}, err error) {
    for k, v := range where {
        ks := strings.Split(k, " ")
        if len(ks) > 2 {
            return "", nil, fmt.Errorf("Error in query condition: %s. ", k)
        }

        if whereSQL != "" {
            whereSQL += " AND "
        }

        fmt.Println(strings.Join(ks, ","))
        switch len(ks) {
        case 1:
            //fmt.Println(reflect.TypeOf(v))
            switch v := v.(type) {
            case NullType:
                fmt.Println()
                if v == IsNotNull {
                    whereSQL += fmt.Sprint(k, " IS NOT NULL")
                } else {
                    whereSQL += fmt.Sprint(k, " IS NULL")
                }
            default:
                whereSQL += fmt.Sprint(k, "=?")
                vals = append(vals, v)
            }
            break
        case 2:
            k = ks[0]
            switch ks[1] {
            case "=":
                whereSQL += fmt.Sprint(k, "=?")
                vals = append(vals, v)
                break
            case ">":
                whereSQL += fmt.Sprint(k, ">?")
                vals = append(vals, v)
                break
            case ">=":
                whereSQL += fmt.Sprint(k, ">=?")
                vals = append(vals, v)
                break
            case "<":
                whereSQL += fmt.Sprint(k, "<?")
                vals = append(vals, v)
                break
            case "<=":
                whereSQL += fmt.Sprint(k, "<=?")
                vals = append(vals, v)
                break
            case "!=":
                whereSQL += fmt.Sprint(k, "!=?")
                vals = append(vals, v)
                break
            case "<>":
                whereSQL += fmt.Sprint(k, "!=?")
                vals = append(vals, v)
                break
            case "in":
                whereSQL += fmt.Sprint("k", "in (?)")
                vals = append(vals, v)
                break
            case "like":
                whereSQL += fmt.Sprint("k", "like ?")
                vals = append(vals, v)
            }
            break
        }
    }
    return
}

This is the way I use SQL build.

func TestWhereBuild(t *testing.T) {
    cond, vals, err := whereBuild(map[string]interface{}{
        "name": "jinzhu", 
        "age in": []int{20, 19, 18},
    })
    if err != nil {
        t.Fatal(err)
    }
    t.Log(cond)
    t.Log(vals)

    db.Where(cond, vals...).Find(&users)

}

This is a method of use.

thank you very much

Was this page helpful?
0 / 5 - 0 ratings

Related issues

littletwolee picture littletwolee  ·  3Comments

easonlin404 picture easonlin404  ·  3Comments

alanyuen picture alanyuen  ·  3Comments

superwf picture superwf  ·  3Comments

koalacxr picture koalacxr  ·  3Comments