为了账号安全,请及时绑定邮箱和手机立即绑定

编写一个可以使用 2 个数据库的应用程序?

编写一个可以使用 2 个数据库的应用程序?

Go
胡说叔叔 2023-07-17 14:20:28
我正在尝试用 Go 编写一个应用程序,能够根据配置连接到 oracle 和 MySQL。我现在遇到的问题是当我使用准备好的语句时。例如,考虑下面的查询Select * from data_table where id = 1下面给出MySQL和oracle中对应的prepared语句MySQL -> Select * from data_table where id = ? ORACLE -> Select * from data_table where id = :val1如果是这样,我维护 2 组查询并根据配置选择查询。有一个更好的方法吗?我想避免保留两组查询的麻烦
查看完整描述

1 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

这很大程度上是通过使用接口来实现的。


假设您创建一个 Web 应用程序并且想要显示用户。


首先,您需要定义一个接口,例如


type Creator interface{

  Create(u User)(User,error)

}


type Reader interface{

  Read(k PrimaryKey)(User, error)

  ListAll()([]User,error)

  ListPaginated(page, offset int)([]User,error)

}


type Updater interface{

  Update(u User)(User, error)

  UpdateByKey(k PrimaryKey, u User)(User, error)

  UpdateMany(...User)error

}


type Deleter interface{

  Delete(u User)error

  DeleteMany(u ...User)error

  DeleteByKey(keys ...PrimaryKey)error

}


type CRUD interface {

  Creator

  Reader

  Updater

  Deleter

}

接下来,为您想要支持的每种数据库类型实现 CRUD 接口。


现在,您可以创建一个处理程序:



// ListHandler uses an interface instead of a concrete type to

// retrieve the data from the databases.

// Not only does this approach make it possible to provide different

// implementations, but it makes unit testing way easier.

//

// "Thou Shalt Write Tests"

func ListHandler(rdr Reader) http.Handler {

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {


        // Pagination ommited for brevity


        // Note that the handler is agnostic of the underlying implementation.

        u, err := rdr.ListAll()

        if err != nil {

            log.Printf("ListHandler: error retrieving user list: %s", err)

            // Do not do this in production! It might give an attacker information

            // Use a static error message instead!

            http.Error(w, err.Error(), http.StatusInternalServerError)

            return

        }


        if err := json.NewEncoder(w).Encode(u); err != nil {

            log.Printf("ListHandler: error encoding user list to JSON: %s", err)

            // See above

            http.Error(w, err.Error(), http.StatusInternalServerError)

        }

    })

}

并设置如下:



func main() {

    // Get your config

    // Then simply use an implementation of CRUD


    var dbConn CRUD

    switch cfg.DbType {

    case "myql":

        // returns your implementation of CRUD using MySQL

        dbConn = createMySQLConnector(cfg)

    case "oracle":

        // returns your implementation of CRUD using Oracle

        dbConn = createOracleConnector(cfg)

    }


    http.Handle("/users/", ListHandler(dbConn))


    log.Fatal(http.ListenAndServe("0.0.0.0:8080", nil))

}


查看完整回答
反对 回复 2023-07-17
  • 1 回答
  • 0 关注
  • 70 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信