Gorm получить текущее соединение с бд

Как я могу получить текущее соединение с БД?

package main

import (
     "github.com/labstack/echo"
      "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/mysql"
   )

 func main() {
     // Echo instance
    e := echo.New()
    db, _ := gorm.Open("mysql", "root:root@/golang")
    defer db.Close()

    gorm.AutoMigrate(&user.User{})
    e.Logger.Fatal(e.Start(":4000"))
}

А вот контроллер, куда я хочу получить пользователя из db

 package controllers

 import (
  "github.com/labstack/echo"
 )

  func login(c echo.Context) error {
  username := c.QueryParam("username")
  }

как я могу получить объект db или мне нужно сделать gorm.Open еще раз? Или создать синглтон для объекта db и импортировать его?

3
0
5 860
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Переменная db, которую возвращает gorm.Open, - это ваш дескриптор базы данных. Вам просто нужно передать его как *gorm.DB тому, кому вы хотите его использовать.

Вот пример того, что вы могли бы сделать, чтобы правильно передать дескриптор базы данных вашему пользовательскому контроллеру:

type UserRepository interface {
    Create(user model.User) error
}

type UserRepositoryMySQL struct {
    db *gorm.DB
}

// The repository you pass to your controller to provide
// an interface with the database
func (u *UserRepositoryMySQL) Create(user model.User) error {
    u.db.Create(&user)
    // handle errors here
    return nil
}

type UserController struct {
    users UserRepository
}

func (u *UserController) Create(ctx echo.Context) {
    var user model.User

    err := ctx.Bind(&user)
    // handle errors

    // validate user
    err := u.users.Create(user)
}

func main() {
    e := echo.New()

    db, _ := gorm.Open("mysql", "root:root@/golang")
    defer db.Close()

    userRepo := repo.UserRepositoryMySQL(db)
    userController := controller.UserController(userRepo)
    ...

    e.POST("/users", userController.Create)
    ...
    e.Logger.Fatal(e.Start(":4000"))
}

Я рекомендую использовать интерфейс для репозитория, так как позже вы можете захотеть интегрировать несколько разных баз данных, и это упрощает имитацию и тестирование вашего контроллера.

Есть два основных способа передать объект подключения. Либо создайте глобальную переменную и передайте ее в методы в качестве аргумента, который вы хотите использовать:

var db *sql.DB

func InitDB(dataSourceName string) {
    var err error
    db, err = sql.Open("postgres", dataSourceName)
    if err != nil {
        log.Panic(err)
    }

    if err = db.Ping(); err != nil {
        log.Panic(err)
    }
}

или вы можете создать структуру и использовать ее в качестве приемника метода для методов после создания экземпляра db.

type DB struct {
   *sqlx.DB
}

func(db *DB) Get() (error)

Но это должно быть поле указателя, которое будет использоваться внутри функций после однократной инициализации экземпляра.

Другие вопросы по теме