我正在尝试抽象我对MySQL数据库的使用,并且我遇到了错误。
我将以对象为例:
package models
// Product : The Product's model
type Product struct {
ID int
Name string
Price int
PictureURL string
}
我将尝试在我的数据库中检索产品id = 1
。为此,假设我已经连接到我的数据库,由下一个变量表示:
var databaseMySQL *sql.DB
为了查询我的数据库,我正在使用这个函数:
// 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}
}
}
此处使用的2个模型是SQLQuery
& Status
。
package models
type SQLQuery struct {
Query string
Args []interface{}
Dest []*interface{}
}
Status
基本上只包含error
和int
。
因此,由于Scan()
作为以下原型Scan func(dest ...interface{}) error
,我可以传递[]*interface{}
作为参数。
如果我是对的,那么我应该能够通过T
类型元素填充 Dest 的元素,然后将它们转换/转换为我需要的类型?
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:此功能只是尝试我的逻辑的基本测试
然而,我收到一个错误:
不能在附加中使用& _product.Name(type * string)作为类型* interface {}: * interface {}是指向接口的指针,而不是接口
对我来说,有两个错误:
cannot use &_product.Name (type *string) as type *interface {}
*interface {} is pointer to interface, not interface
首先,为什么我不能使用接口存储我的字符串?
其次,由于我在字符串上传递指针,interface{}
有什么问题?它应该是* interface {},不是吗?
除了给定的代码之外,你可以通过在切片变量的名称之后添加...
来像我一样传递切片
mysqlproduct.go
// 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
// 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: ""}
}
答案 0 :(得分:1)
接口可以保存指针。很少有理由指向接口。
如果您将类型更改为[] interface {},它应该可以正常工作。
如果你真的想要接口指针,出于某种原因,你必须首先将该字段存储在一个接口中,然后获得指向它的指针。
即:
var i interface{} = &_product.Name
append(dest, &i)