Как передать параметр соединения db в main.go?
У меня проблемы с моими текущими работами. Я создаю приложения, используя beego Framework, я новичок в golang.
Сначала я создаю другой пакет, называемый utils, и из этого пакета я пишу несколько кодов для доступа к моим базам данных.
func InitFirebird() {
var (
dbDriver = beego.AppConfig.String("DB_CONNECTION")
dbUsername = beego.AppConfig.String("DB_USERNAME")
dbPassword = beego.AppConfig.String("DB_PASSWORD")
dbServer = beego.AppConfig.String("DB_HOST")
// dbPort = beego.AppConfig.String("DB_PORT")
dbFileName = beego.AppConfig.String("DB_DATABASE")
)
conn, _ := sql.Open(dbDriver, dbUsername+":"+dbPassword+"@"+dbServer+"/"+dbFileName)
defer conn.Close()
}
После этого я захожу в main.go и настраиваю свою функцию инициализации и функцию main следующим образом:
func init() {
utils.InitFirebird()
}
func main() {
if beego.BConfig.RunMode == "dev" {
beego.BConfig.WebConfig.DirectoryIndex = true
beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
}
var n int
conn.QueryRow("SELECT Count(*) FROM rdb$relations").Scan(&n)
fmt.Println("Relations count=", n)
beego.Run()
}
Когда я запускаю свои приложения, появляется сообщение об ошибке:
\main.go:23:2: undefined: conn
Как я могу решить это?
Anyhelp по достоинству оценят
1 ответ
Во-первых, если вы хотите получить доступ к чему-либо из другого пакета, его необходимо экспортировать. В Go, если вы хотите экспортировать что-то, вы называете это с первой буквой в верхнем регистре (в вашем случае это должно быть Conn
вместо conn
).
Во-вторых, когда вы используете defer
он будет выполнен, когда функция вернется. В вашем случае он сразу возвращается, поэтому соединение немедленно закрывается.
Решение:
var Conn *sql.DB
func InitFirebird() {
var (
dbDriver = beego.AppConfig.String("DB_CONNECTION")
dbUsername = beego.AppConfig.String("DB_USERNAME")
dbPassword = beego.AppConfig.String("DB_PASSWORD")
dbServer = beego.AppConfig.String("DB_HOST")
// dbPort = beego.AppConfig.String("DB_PORT")
dbFileName = beego.AppConfig.String("DB_DATABASE")
)
Conn, _ = sql.Open(dbDriver, dbUsername+":"+dbPassword+"@"+dbServer+"/"+dbFileName)
}
Теперь в вашем основном пакете:
func init() {
utils.InitFirebird()
}
func main() {
if beego.BConfig.RunMode == "dev" {
beego.BConfig.WebConfig.DirectoryIndex = true
beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
}
var n int
defer utils.Conn.Close() // <-- Close here
utils.Conn.QueryRow("SELECT Count(*) FROM rdb$relations").Scan(&n)
fmt.Println("Relations count=", n)
beego.Run()
}
Вот Close()
не будет казнен сразу, потому что beego.Run()
будет блокировать.
PS: Передача соединения с БД с использованием глобальной переменной не рекомендуется. Если вы хотите узнать больше, проверьте это: https://www.alexedwards.net/blog/organising-database-access