我想创建一个迷你框架,它采用一个简单的结构并从中创建一个完整的结构。我已经开始了,“findOne,update,create,delete”正在运行。我没有问题创建一个findAll方法。更清楚,我不知道如何使用反射来解决我的ptr到一个struct数组。
这是findOne函数的一个小例子。
type company struct {
Id int
Name string
}
comp.InitModel(newDbConnection(), &comp)
在InitModel中,我可以使用以下内容填充指向公司的指针:
//m.caller = pointer to the ptr to comp (struct)
callerV := reflect.ValueOf(m.caller)
CallerField := callerV.Elem()
var values []interface{}
for _, e := range m.columns {
values = append(values, CallerField.FieldByName(e.name).Addr().Interface())
}
err := r.Scan(values...)
if err != nil {
return err
}
现在我想创建一个像这样调用的findAll方法
var companies []company
comp.InitModel(newDbConnection(), &comp)
comp.FindAll(&companies) //in this is the db query and scan
fmt.Println(companies) //here should be the result
但我有一个问题是通过[]界面工作来反映。
func (m *Model) FindAll(test []interface{}, c *Condition) error {
//get the sql statement from the struct
stmt := PrepairStmt(m, c)
rows, err := m.db.Query(stmt.selectParse(), c.arguments...)
if err != nil {
return err
}
defer rows.Close()
callerV := reflect.ValueOf(m.caller)
CallerField := callerV.Elem()
for rows.Next() {
var values []interface{}
for _, e := range m.columns {
values = append(values, CallerField.FieldByName(e.name).Addr().Interface())
}
err = rows.Scan(values...)
if err != nil {
return err
}
valuePtr := reflect.New(reflect.TypeOf(test).Elem())
test = reflect.Append(test,reflect.ValueOf(values))
}
return nil
}
多数民众赞成是我最近的尝试。 也许有人可以帮我这个。 我真的很感激
答案 0 :(得分:2)
使用interface{}
代替[]interface{}
作为参数类型:
func (m *Model) FindAll(result interface{}, c *Condition) error {
stmt := PrepairStmt(m, c)
rows, err := m.db.Query(stmt.selectParse(), c.arguments...)
if err != nil {
return err
}
defer rows.Close()
// resultv is the result slice
resultv := reflect.ValueOf(result).Elem()
// rowt is the struct type
rowt := resultv.Type().Elem()
// allocate a value for the row
rowv := reflect.New(rowt).Elem()
// collect values for scan
var values []interface{}
for _, e := range m.columns {
values = append(values, rowv.FieldByName(e.name).Addr().Interface())
}
for rows.Next() {
err = rows.Scan(values...)
if err != nil {
return err
}
// Append struct to result slice. Because the struct
// is copied in append, we can reuse the struct in
// this loop.
resultv.Set(reflect.Append(resultv, rowv))
}
return nil
}
像这样使用:
var companies []company
comp.InitModel(newDbConnection(), &comp)
comp.FindAll(&companies) //in this is the db query and scan