无法导入本地包

时间:2017-11-17 04:45:39

标签: go

我决定尝试将我的项目分解为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))
}

1 个答案:

答案 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的多个实例时,关闭才有意义,并且存在在等待连接时它们将开始阻塞的危险。如果你只有一个由整个程序共享,那么你应该没有调用延迟关闭。