douhuan9289 2016-11-05 10:18
浏览 58

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

I'm implementing a database API. I have models. I need to implement CRUD actions to each model. For now I create an individual GetAllModels function and Get method for each model. How could I do that once for all models and just pass around some variables if needed?

The pattern below I use for each model:

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
}

But what actually changes from model to model is a query string and a type of slice objects.

How to make one universal GetAll function and Get method for all future models?

  • 写回答

1条回答 默认 最新

  • dsft8327 2016-11-05 22:30
    关注

    I haven't tested this, but it should work. If you receive the table and column names (or you know them) for each request and you can just fetch from the db as interface passing the table and column as variables.

    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
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?