如何在Golang中为任何模型实现基本的CRUD操作?

时间:2016-11-05 10:18:59

标签: go sqlite

我正在实施数据库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方法?

1 个答案:

答案 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
}