mysql - 编写一个可以使用 2 个数据库的应用程序?
问题描述
我正在尝试在 Go 中编写一个能够基于配置连接到 oracle 和 MySQL 的应用程序。我现在遇到的问题是当我使用准备好的语句时。例如,考虑下面的查询
Select * from data_table where id = 1
MySQL和oracle中对应的prepared statement如下
MySQL -> Select * from data_table where id = ?
ORACLE -> Select * from data_table where id = :val1
如果是这样,我维护了 2 组查询并根据配置选择查询。有一个更好的方法吗?
我想避免保留两组查询的麻烦
解决方案
很大程度上是通过使用接口。
假设您创建了一个 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))
}
hth
推荐阅读
- ios - 将自定义单元格插入 TableView
- jquery - StickyBits 不粘
- c++ - 尝试解除分配二叉搜索树时出错(仅适用于原始数据类型)
- python - 我有一个包含字典的列表。如何附加到特定键的值?
- vb.net - 使用来自 JSON 的 LINQ 从属性中获取所有值?
- c++ - C++中程序执行中带cout和不带cout的时间差
- node.js - 从 Stripe 结帐会话中检索帐单地址?
- php - 在flutter中获取JSON数据返回NULL
- reporting - Report Builder 3 中的每股成本是如何计算的?
- javascript - 用 div / class 隐藏 li 项目