【发布时间】:2020-09-26 03:33:48
【问题描述】:
我正在使用 Go 开发一个 Web API,并且有很多冗余的数据库查询扫描代码。
func (m *ContractModel) WorkQuestions(cid int) ([]models.WorkQuestion, error) {
results, err := m.DB.Query(queries.WORK_QUESTIONS, cid)
if err != nil {
return nil, err
}
var workQuestions []models.WorkQuestion
for results.Next() {
var wq models.WorkQuestion
err = results.Scan(&wq.ContractStateID, &wq.QuestionID, &wq.Question, &wq.ID, &wq.Answer, &wq.Compulsory)
if err != nil {
return nil, err
}
workQuestions = append(workQuestions, wq)
}
return workQuestions, nil
}
func (m *ContractModel) Questions(cid int) ([]models.Question, error) {
results, err := m.DB.Query(queries.QUESTIONS, cid)
if err != nil {
return nil, err
}
var questions []models.Question
for results.Next() {
var q models.Question
err = results.Scan(&q.Question, &q.Answer)
if err != nil {
return nil, err
}
questions = append(questions, q)
}
return questions, nil
}
func (m *ContractModel) Documents(cid int) ([]models.Document, error) {
results, err := m.DB.Query(queries.DOCUMENTS, cid)
if err != nil {
return nil, err
}
var documents []models.Document
for results.Next() {
var d models.Document
err = results.Scan(&d.Document, &d.S3Region, &d.S3Bucket, &d.Source)
if err != nil {
return nil, err
}
documents = append(documents, d)
}
return documents, nil
}
我需要概括这段代码,以便我可以将结果*sql.Rows 传递给一个函数并获得一个包含扫描行的结构切片。我知道 sqlx 包中有一个StructScan 方法,但由于我有大量使用 go 标准 database/sql 包编写的代码,因此无法使用该方法。
使用反射包,我可以创建一个通用的 StructScan 函数,但反射包不能从传递的 interface{} 类型创建一个结构切片。我需要实现的是如下
func RowsToStructs(rows *sql.Rows, model interface{}) ([]interface{}, error) {
// 1. Create a slice of structs from the passed struct type of model
// 2. Loop through each row,
// 3. Create a struct of passed mode interface{} type
// 4. Scan the row results to a slice of interface{}
// 5. Set the field values of struct created in step 3 using the slice in step 4
// 6. Add the struct created in step 3 to slice created in step 1
// 7. Return the struct slice
}
我似乎找不到一种方法来扫描作为模型参数传递的结构并使用反射包创建一个切片。有什么解决方法吗?还是我看问题的方式有误?
结构字段具有从结果返回的正确列数和正确的顺序
【问题讨论】:
-
结果集中的列和结构体字段有什么关联?
-
结构字段从结果返回的列数正确且顺序正确
-
sqlx与标准database/sql包一起使用。而且,如果您无论如何都必须重新编写代码以适应您的新抽象,为什么不直接使用sqlx,而不是重新发明轮子? -
@Flimzy sqlx 实现了我想要实现的部分,而不是完整的实现
-
@S.Sandeep:sqlx 不做哪一部分?
标签: sql go reflection refactoring generalization