БД подключения в golang

Где я могу поместить файлы инициализации, такие как языки, соединение db и т. д., в mvc structur golang (beego, revel)?

Я пытался использовать в контроллере, но это не очень хорошо.

Хорошим решением было бы создать базовый контроллер и разместить здесь все начальные соединения, языки и т. д.? или есть другой способ (лучше)?


person Patryk Gtfo    schedule 10.09.2016    source источник


Ответы (2)


Вы можете использовать глобальные переменные, но я не предлагаю этого делать. Что происходит в более сложных приложениях, где логика базы данных распределена по нескольким пакетам? Лучше использовать внедрение зависимостей:

Файл: main.go

package main

import (
    "bookstore/models"
    "database/sql"
    "fmt"
    "log"
    "net/http"
)

type Env struct {
    db *sql.DB
}

func main() {
    db, err := models.NewDB("postgres://user:pass@localhost/bookstore")
    if err != nil {
        log.Panic(err)
    }
    env := &Env{db: db}

    http.HandleFunc("/books", env.booksIndex)
    http.ListenAndServe(":3000", nil)
}

func (env *Env) booksIndex(w http.ResponseWriter, r *http.Request) {
    if r.Method != "GET" {
        http.Error(w, http.StatusText(405), 405)
        return
    }
    bks, err := models.AllBooks(env.db)
    if err != nil {
        http.Error(w, http.StatusText(500), 500)
        return
    }
    for _, bk := range bks {
        fmt.Fprintf(w, "%s, %s, %s, £%.2f\n", bk.Isbn, bk.Title, bk.Author, bk.Price)
    }
}

Файл: models/db.go

package models

import (
    "database/sql"
    _ "github.com/lib/pq"
)

func NewDB(dataSourceName string) (*sql.DB, error) {
    db, err := sql.Open("postgres", dataSourceName)
    if err != nil {
        return nil, err
    }
    if err = db.Ping(); err != nil {
        return nil, err
    }
    return db, nil
}
person Alex Pliutau    schedule 11.09.2016
comment
Это из сообщения в блоге Алекса Эдвардса: alexedwards.net/blog/organising-database- доступ - person Niko Kovacevic; 09.07.2018

Я всегда делаю несколько пакетов, в которых храню переменные среды.

Например main.go

package main

import (
    "net/http"
     env "github.com/vardius/example/enviroment"
)

func main() {
    //some extra code here, http srever or something
    defer env.DB.Close()
}

конец внутри enviroment директория env.go

package env

import (
    "database/sql"

    _ "github.com/go-sql-driver/mysql"
)

var (
    DB     *sql.DB
)

func connectToDB(dbURL string) *sql.DB {
    conn, err := sql.Open("mysql", dbURL)
    //check for err

    return conn
}

func init() {
    DB = connectToDB("root:password@tcp(127.0.0.1:3306)/test")
}

таким образом вы инициализируете свою БД и можете использовать ее во всех частях вашего приложения, вводя env

Конечно, это решение имеет некоторые недостатки. Во-первых, код труднее обдумывать, потому что зависимости компонента неясны. Во-вторых, тестирование этих компонентов усложняется, а параллельное выполнение тестов практически невозможно. При глобальных подключениях тесты, которые затрагивают одни и те же данные в серверной службе, не могут выполняться параллельно.

Есть отличная статья о внедрении зависимостей с помощью Go.

Я надеюсь, что вы найдете это полезным

person vardius    schedule 10.09.2016