我决定尝试将我的项目分解为MVC类型视图,所以要开始我想将所有路由放入控制器文件夹,然后将数据库连接放入另一个名为db的文件夹中。
我无法弄清楚如何使数据库连接顺利进行。当所有文件都在我的package main
中时,我刚刚在main中调用了InitDb()
,在主包中的所有其他文件中,我都可以访问db变量。现在,我将数据库作为下载包并导入它,没有任何内容被识别。
我也不知道在哪里拨打InitDb()
和defer db.Close()
,因为它不是主要的。
分贝/ db.go
package database
import (
"fmt"
"database/sql"
)
var db *sql.DB
const (
dbhost = "localhost"
dbuser = "root"
dbpass = "password"
dbname = "user"
)
func InitDb() {
var err error
connectionString := fmt.Sprintf("%s:%s@/%s", dbuser, dbpass, dbname)
db, err = sql.Open("mysql", connectionString)
if err != nil {
panic(err)
}
err = db.Ping()
if err != nil {
panic(err)
}
fmt.Println("Successfully connected!")
}
控制器/ index.go
package controllers
import (
"net/http"
"fmt"
"db"
"github.com/gorilla/mux"
)
func TestHandler(r *mux.Router)
r.HandleFunc("/index", test).Methods("GET")
}
func test(w http.ResponseWriter, r *http.Request) {
// database undefined
err := database.QueryRow("some sql statement")
CheckErr(err)
}
main.go
package main
import (
"net/http"
_ "github.com/go-sql-driver/mysql"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
controllers.TestHandler(r)
log.Fatal(http.ListenAndServe("localhost:8000", r))
}
答案 0 :(得分:1)
虽然不需要,但最好让包名与其所在的文件夹相同,所以要么:
db/db.go
package db
// ...
或者做:
database/db.go
package database
// ...
我不建议将两者混合使用。
您可以让数据库包导出Close
函数,并在完成后主要调用它。
database/db.go
package database
import (
"fmt"
"database/sql"
)
var db *sql.DB
func Close() {
db.Close()
}
// ...
main.go
package main
import "database"
func main() {
defer database.Close()
// ...
}
或者在这种情况下不要关闭它。当主要退出时,*sql.DB
在程序之外不会保持活动状态,如果程序未运行,它将不会占用连接槽。只有当您使用*sql.DB
的多个实例时,关闭才有意义,并且存在在等待连接时它们将开始阻塞的危险。如果你只有一个由整个程序共享,那么你应该没有调用延迟关闭。