我正在实施数据库API。我有模特。我需要为每个模型实现CRUD操作。现在我为每个模型创建一个单独的GetAllModels
函数和Get
方法。我怎么能为所有模型做一次,如果需要的话只传递一些变量?
我在每个模型中使用的模式:
type City struct {
Attr1 string
Attr2 string
}
type Country struct {
Attr1 string
Attr2 string
}
func GetAllCities(db *sqlx.DB) ([]*City, error) {
items := []*City{}
err := db.Select(&items, "SELECT * FROM cities")
// check err
return items, nil
}
func (m *City) Get(db *sqlx.DB, id string) error {
if err := db.Get(m, "SELECT FROM cities WHERE id = ?", id); err != nil {
return err
}
return nil
}
func GetAllCountries(db *sqlx.DB) ([]*Country, error) {
items := []*Country{}
err := db.Select(&items, "SELECT * FROM countries")
// check err
return items, nil
}
func (m *Country) Get(db *sqlx.DB, id string) error {
if err := db.Get(m, "SELECT FROM countries WHERE id = ?", id); err != nil {
return err
}
return nil
}
但实际上从模型到模型的变化是切片对象的查询字符串和类型。
如何为所有未来的模型制作一个通用GetAll
函数和Get
方法?
答案 0 :(得分:0)
我没有对此进行测试,但它应该可行。如果您收到每个请求的表名和列名(或者您知道它们),您只需从数据库中获取interface
,将表和列作为变量传递。
package main
import (
"errors"
"fmt"
"github.com/jmoiron/sqlx"
)
func selectAll(table string) string {
return fmt.Sprintf("SELECT * FROM %s", table)
}
func selectWhere(table string, column string) string {
return fmt.Sprintf("SELECT * FROM %s WHERE %s = ?", table, column)
}
func validTableStr(table string) bool {
// real validation here
return true
}
func validColumnStr(table string, column string) bool {
// real validation here
return true
}
func GetAll(db *sqlx.DB, table string) ([]interface{}, error) {
if !validTableStr(table) {
return nil, errors.New("invalid table name")
}
items := []interface{}{}
err := db.Select(&items, selectAll(table))
return items, err
}
func GetWhere(db *sqlx.DB, table string, column string, value interface{}) ([]interface{}, error) {
if !validTableStr(table) {
return nil, errors.New("invalid table name")
}
if !validColumnStr(table, column) {
return nil, errors.New("invalid column name")
}
items := []interface{}{}
err := db.Select(&items, selectWhere(table, column), value)
return items, err
}