【发布时间】:2021-02-14 12:10:27
【问题描述】:
到目前为止,Go 最难的部分是理解如何组织代码。表面上看起来非常简单,但每次我尝试做任何事情时,我都会遇到循环导入或“exported func Start 返回未导出的类型 models.dbStore,使用起来很烦人”之类的东西。
使用以下代码如何调用db.Close() 或者我真的不明白我应该如何为我的模型提供数据库。这是我得到的:
App.go
package app
import (
"database/sql"
// Comment
_ "github.com/mattn/go-sqlite3"
)
var (
// DB The database connection
db *sql.DB
)
// Setup Sets up the many many app settings
func Setup() {
d, err := sql.Open("sqlite3", "./foo.db")
if err != nil {
panic(err)
}
// TODO: How does the DB get closed?
// defer db.Close()
db = d
}
// GetDB Returns a reference to the database
func GetDB() *sql.DB {
return db
}
Users.go
package models
import (
"github.com/proj/org/app"
)
// User struct
type User struct {
ID int
}
// CreateUser Creates a user
func (u *User) CreateUser() (int64, error) {
// For the sake of brevity just make sure you can
// "connect" to the database
if err := app.GetDB().Ping(); err != nil {
panic(err)
}
return 1234, nil
}
main.go
package main
import (
"fmt"
"net/http"
_ "github.com/mattn/go-sqlite3"
"github.com/proj/org/app"
"github.com/proj/org/models"
)
func homeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "You are home")
}
func subscribeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Subscribing...")
u := models.User{}
u.CreateUser()
}
func main() {
fmt.Println("Running")
app.Setup()
http.HandleFunc("/", homeHandler)
http.HandleFunc("/subscribe", subscribeHandler)
err := http.ListenAndServe(":9090", nil)
if err != nil {
panic(err)
}
}
我想过做一个app.Shutdown(),但这不适用于我最常见的用例CTRL-C。如果我不关闭数据库,似乎数据库连接只会增长......只是试图理解。
【问题讨论】:
-
随着项目的发展和成熟,您可能希望稍微改变一下它。就目前而言,您的
app和main包都与数据库耦合,从设计的角度来看,您可能希望避免这种情况。将它们解耦将有助于缓解您的一些依赖问题,但需要在设计时更加小心。 -
@Adrian 你有没有显示这种解耦的 goto 示例应用程序?我看过一些,例如 Netlify GoTrue API,但有时我很难理解大局,因为有太多的包/抽象。
标签: go