用于MySQL查询抽象的接口指针

Slice of pointers to interface for MySQL queries abstractions

我试图抽象我的MySQL数据库的用途,但遇到了一个错误。

我将举一个例子:

1
2
3
4
5
6
7
8
9
package models

// Product : The Product's model
type Product struct {
    ID         int
    Name       string
    Price      int
    PictureURL string
}

我将尝试在我的数据库中检索产品id = 1。为此,假设我已经与数据库建立了连接,该连接由下一个变量表示:

1
var databaseMySQL *sql.DB

为了查询我的数据库,我使用以下函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// QueryMySQL query our MySQL database
func QueryMySQL(sqlquery model.SQLQuery) model.Status {

    // prepare the query
    stmtOut, err := databaseMySQL.Prepare(sqlquery.Query)
    if err != nil {
        return model.Status{Code: http.StatusInternalServerError, Error: err}
    }
    defer stmtOut.Close()

    // Run the query
    err = stmtOut.QueryRow(sqlquery.Args).Scan(sqlquery.Dest)
    if err != nil {
        return model.Status{Code: http.StatusInternalServerError, Error: err}
    } else {
        return model.Status{Code: http.StatusOK, Error: nil}
    }
}

这里使用的两种型号是SQLQueryStatus

1
2
3
4
5
6
7
package models

type SQLQuery struct {
    Query string
    Args  []interface{}
    Dest  []*interface{}
}

Status基本上包含一个error和一个int

因此,由于Scan()作为以下原型Scan func(dest ...interface{}) error,我可以传递一个[]*interface{}作为参数。

如果我是对的,那么我应该能够用T类型元素填充dest的元素,然后将它们强制转换成我需要的类型?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func GetProductByID(ID int) (model.Product, model.Status) {

    //"SELECT ID, Name, Price, PictureURL FROM Products WHERE ID = ?"
    var _product model.Product

    // HERE IS THE PROBLEM
    var dest []*interface{}
    append(dest, &_product.Name)
    append(dest, &_product.Price)
    append(dest, &_product.PictureURL)
    // HERE IS THE PROBLEM

    status := QueryMySQL(model.SQLQuery{
        Query:"SELECT Name, Price, PictureURL FROM Products WHERE ID = ?",
        Args:  []interface{}{ID},
        Dest:  dest})

    return _product, model.Status{Code: http.StatusOK, Error: nil}
}

PS:这个函数只是一个测试我逻辑的基本测试

但是,我得到一个错误:

cannot use &_product.Name (type *string) as type *interface {} in append:
*interface {} is pointer to interface, not interface

对我来说,有两个错误:

  • 埃多克斯1〔10〕
  • 江户十一〔11〕。
  • 小精灵

    首先,为什么我不能使用一个接口来存储我的字符串?

    其次,因为我在字符串上传递指针,所以interface{}有什么问题?它应该是*接口,不是吗?

    正确的密码,感谢大卫·布德沃思的回答

    除了给定的代码之外,您还可以像我一样将slice作为varargs传递,方法是在slice变量的名称后面添加...

    mysqlproduct.go网站

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // GetProductByID returns a Product based on a given ID
    func GetProductByID(ID int) (model.Product, model.Status) {

        _product := model.Product{
            ID: ID}

        status := QueryMySQL(&model.SQLQuery{
            Query:"SELECT Name, Price, PictureURL FROM Products WHERE ID = ?",
            Args:  []interface{}{_product.ID},
            Dest:  []interface{}{&_product.Name, &_product.Price, &_product.PictureURL}})

        if status.Code != http.StatusOK {
            return _product, status
        }

        return _product, model.Status{Code: http.StatusOK, Error:""}
    }

    去mysql.go

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // QueryMySQL query our MySQL database
    func QueryMySQL(sqlquery *model.SQLQuery) model.Status {

        stmtOut, err := databaseMySQL.Prepare(sqlquery.Query)
        if err != nil {
            return model.Status{Code: http.StatusInternalServerError, Error: err.Error()}
        }
        defer stmtOut.Close()

        // Run the query
        err = stmtOut.QueryRow(sqlquery.Args...).Scan(sqlquery.Dest...)
        if err != nil {
            return model.Status{Code: http.StatusInternalServerError, Error: err.Error()}
        }
        defer stmtOut.Close()

        return model.Status{Code: http.StatusOK, Error:""}
    }


    接口可以保存指针。很少有理由将指针指向接口。

    如果您将类型更改为[]接口它应该可以工作。

    如果您真的想要指向接口的指针,出于某种原因,您必须首先将字段存储在接口中,然后获取指向该字段的指针。

    IE:

    1
    2
    var i interface{} = &_product.Name
    append(dest, &i)