我正在使用mysql数据库,并且有许多与数据库交互的不同函数/方法。对于每个功能,我必须提供数据库凭证,例如
ReadAll.go
func ReadAll() {
db, err := sql.Open("mysql",
"user:password@tcp(127.0.0.1:3306)/hello")
if err != nil {
log.Fatal(err)
}
defer db.Close()
}
“mysql”的一部分, “user:password @ tcp(127.0.0.1:3306)/ hello”永远不会更改,我将其提供给与DB交互的每个Function。我想知道如何创建一个新文件说 DataBase.go 将这些凭据放入某个全局变量然后在需要这些字符串时引用?这样,如果我必须更改凭据,我只需要在一个地方更改它们。 我想做像
这样的事情Database.go
const GlobalDB := "mysql","user:password@tcp(127.0.0.1:3306)/hello"
然后
ReadAll.go
func ReadAll() {
db, err := sql.Open(GlobalDB)
if err != nil {
log.Fatal(err)
}
defer db.Close()
}
我是Golang的新手,但试图解决这个问题。
答案 0 :(得分:3)
我可能会通过打开一次数据库会话,然后将此会话传递给可能需要它的任何函数或方法。这有一些潜在的问题:
另一种方法是使用一个返回DB sesssion的函数,而不是执行:
$(document).ready(function(){
$("#select_users").on('change', function(){
var user = $(this).val();
var path = $("#btn_book").attr("data-book-path");
$("#btn_book").attr('href', path + "/" + user);
//#btn_book is the id of our link, where we'll change its href to the selected user
});
});
您执行以下操作:
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/hello")
如果您想要更多灵活性,可以使用包含所需数据的结构,然后从中构建数据库连接参数。
func dbSession() (sql.DB, error) {
return sql.Open("mysql", "credentials")
}
func ReadAll() {
db, err := dbSession()
if err != nil {
log.Fatal(err)
}
defer db.Close()
}
另请注意type dbData struct {
DBType, DBName, User, Host, Password string
}
var DBData dbData
func dbSession() (*sql.DB, error) {
return sql.Open(DBData.DBType, fmt.Sprintf("%s:%s@tcp(%s)/%s", DBData.User, DBData.Password, DBData.Host, DBData.DBName)
}
的文档中的以下内容:
返回的数据库对于多个goroutine和并发使用是安全的 维护自己的空闲连接池。因此,Open功能 应该只召唤一次。很少需要关闭数据库。
答案 1 :(得分:1)
您可以使用凭据轻松创建新文件。只需将文件放在主包主文件中即可。
package main
var myDBConnectionString := "mysql://...."
编译源代码时将包含此内容。
问题是,每次必须连接到另一个数据库时都必须重新编译代码。想想开发系统与生产系统。这些系统中的数据库凭据应该不同,对吧? :)
要解决这个问题,有一个配置文件是很常见的。因此,您无需重新编译代码即可更改凭据。
我还有另一个想法 - 只需连接到db一次,然后全局访问此资源。 包主要
import (
"fmt"
)
var myDb = "example"
func main() {
fmt.Println("Hello, playground")
doSomthingWithDatabase()
}
func doSomthingWithDatabase() {
fmt.Println("We can access a global variable here, see", myDb)
}
https://play.golang.org/p/npZ6Z49ink
对于配置处理,您可以在此处查看 https://blog.gopheracademy.com/advent-2014/reading-config-files-the-go-way/
答案 2 :(得分:1)
hiboot-data提供了符合您要求的开箱即用的启动器,该启动器为github.com/hidevopsio/hiboot-data/starter/gorm,或者您可以使用hiboot来实现自己的启动器框架,然后可以在任何地方注入以与创建数据库配置脱钩。
package service
import (
"errors"
"hidevops.io/hiboot-data/examples/gorm/entity"
"hidevops.io/hiboot-data/starter/gorm"
"hidevops.io/hiboot/pkg/app"
"hidevops.io/hiboot/pkg/utils/idgen"
)
type UserService interface {
AddUser(user *entity.User) (err error)
GetUser(id uint64) (user *entity.User, err error)
GetAll() (user *[]entity.User, err error)
DeleteUser(id uint64) (err error)
}
type UserServiceImpl struct {
// add UserService, it means that the instance of UserServiceImpl can be found by UserService
UserService
repository gorm.Repository
}
func init() {
// register UserServiceImpl
app.Component(newUserService)
}
// will inject BoltRepository that configured in github.com/hidevopsio/hiboot/pkg/starter/data/bolt
func newUserService(repository gorm.Repository) UserService {
repository.AutoMigrate(&entity.User{})
return &UserServiceImpl{
repository: repository,
}
}
func (s *UserServiceImpl) AddUser(user *entity.User) (err error) {
if user == nil {
return errors.New("user is not allowed nil")
}
if user.Id == 0 {
user.Id, _ = idgen.Next()
}
err = s.repository.Create(user).Error()
return
}
func (s *UserServiceImpl) GetUser(id uint64) (user *entity.User, err error) {
user = &entity.User{}
err = s.repository.Where("id = ?", id).First(user).Error()
return
}
func (s *UserServiceImpl) GetAll() (users *[]entity.User, err error) {
users = &[]entity.User{}
err = s.repository.Find(users).Error()
return
}
func (s *UserServiceImpl) DeleteUser(id uint64) (err error) {
err = s.repository.Where("id = ?", id).Delete(entity.User{}).Error()
return
}