3 回答

TA贡献1893条经验 获得超10个赞
使用方法而不是函数。这允许您使用这些方法的接收器传递处理程序所需的任何信息:
type MyHandler struct {
DB *gorm.DB
}
func (m MyHandler) IndexHandler(w http.ResponseWriter, r *http.Request) {
// Use m.DB here
}
主要内容:
handler:=mypkg.MyHandler{DB:gormDB}
r.Get("/", handler.IndexHandler)
在某些情况下,闭包更有意义。
func GetIndexHandler(db *gorm.DB) func(http.ResponseWriter,*http.Request) {
return func(w http.ResponseWriter,req *http.Request) {
// Implement index handler here, using db
}
}
func main() {
...
r.Get("/", GetIndexHandler(db))

TA贡献1797条经验 获得超4个赞
在数据库/查询函数本身中。我个人为控制器制作了一个单独的包,为服务制作了一个单独的包。我在控制器(具有我的处理程序函数)中处理所有请求验证和HTTP内容。然后,如果一切都检查出来,我打电话给一个服务包。服务包是调用数据库以及任何其他服务或 API 集成的服务包。
然而,无论你在哪里调用数据库,通常你都会调用一个包,该包具有一堆具有友好名称的查询函数,例如或类似名称。好吧,该函数正是您传递或对象的位置。dbdb.GetAccountByIDdb*sql.DB*gorm.DB
一个例子是...
package db
func GetAccountByID(id int, db *gorm.DB) (*model.Account, error) {
if db == nil {
db = conn // conn is the package level db connection object
}
//...
}
通常,当服务器启动时,我会创建数据库连接(用作连接池),因此实际上没有必要将其传递到函数中。那么,为什么要这样做呢?嗯,这是因为测试。您不希望数据库处理程序访问包级数据库连接对象,因为对该函数进行隔离测试变得更加困难。
因此,此函数签名为您提供了可测试性,并且初始条件仍然使用单个中央数据库连接对象(如果为数据库值传入),除非您正在测试,否则该对象始终是。ifnilnil
这只是一种方法,但我已经成功使用了多年。
- 3 回答
- 0 关注
- 109 浏览
添加回答
举报