其他包上的 GORM DB 连接

标签 go

我开始学习 Go,阅读有关指针的内容,并希望拆分我的数据库连接和 API 处理函数。已经尝试过自己,遵循此 solution ,但是当我尝试读取数据时,出现此错误

[2018-06-26 21:59:45] sql: 数据库已关闭 这是我的源代码。

db.go

package db

import (
"fmt"

"github.com/jinzhu/gorm"
"github.com/joho/godotenv"

"os"
)

var Db *gorm.DB

func Open() error {

  var err error
  _ = godotenv.Load(".env")

  dbType := os.Getenv("DB_TYPE")
  dbConnString := os.Getenv("DB_CONN_STRING")

  Db, err = gorm.Open(dbType, dbConnString)
  if err != nil {
    fmt.Println(err)
  }
  Db.LogMode(true)
  defer Db.Close()

  return err
}

func Close() error {
    return Db.Close()
}

person.go

package model

import (
    "github.com/jinzhu/gorm"
    "github.com/gin-gonic/gin"
    "fmt"
    "namastra/gin/result"
    "namastra/gin/db"
)

type Person struct {
    gorm.Model
    FirstName string `json:”firstname”`
    LastName  string `json:”lastname”`
}

/*var db *gorm.DB
var err error*/

func GetPeople(c *gin.Context) {

    var people []result.Person
    if err := db.Db.Select("ID,first_name,last_name").Find(&people).Error; err != nil {
        c.AbortWithStatus(404)
        fmt.Println(err)
    } else {
        c.JSON(200, people)
    }
}

main.go

package main

import (
    "log"
    "namastra/gin/handler"
    "namastra/gin/model"
    "net/http"
    "time"

    "github.com/adam-hanna/jwt-auth/jwt"
    "github.com/gin-gonic/gin"
    _ "github.com/jinzhu/gorm/dialects/postgres"

    "namastra/gin/db"
)

func main() {
if err := db.Open(); err != nil {
    // handle error
    panic(err)
}
defer db.Close()

router := gin.Default()
router.Use(gin.Recovery())
private := router.Group("/auth")

....(ommited)

router.GET("/", gin.WrapH(regularHandler))
router.GET("/people/", model.GetPeople)
router.Run("127.0.0.1:3000")
}

抱歉我的英语不好,感谢任何形式的帮助。

谢谢。

编辑1:案件已结。

解决方案是删除

defer Db.Close()

来自 db.go。

edi2:更新一些我在go项目工作中学到的知识

最佳答案

开始学习 GO 时,通常我们将所有内容都放在单个 main.go 文件中,并且我们考虑将代码拆分到多个文件中。

这就是依赖注入(inject)发挥作用的时候了。

我们可以创建像这样的Env来存储处理程序。

type Env struct {
    db *sql.DB
    logger *log.Logger
    templates *template.Template
}

并在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
}

ma​​in.go 文件

package main

import (
    "namastra/gin/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("/peoples", env.peoplesIndex)
    http.ListenAndServe(":3000", nil)
}

func (env *Env) peoplesIndex(w http.ResponseWriter, r *http.Request) {
   # ...
}

以及models/people.go

package models

import "database/sql"

type Book struct {
    Isbn   string
    Title  string
    Author string
    Price  float32
}

func AllPeoples(db *sql.DB) ([]*People, error) {
    rows, err := db.Query("SELECT * FROM peoples")
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    # ... ommited for simplicity
}

您可以在 Alex Edwards post 中阅读完整的代码和说明

关于其他包上的 GORM DB 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51046557/

相关文章:

go - 是否可以在 Go 中同时等待 channel 和文件描述符?

testing - 创建用于自动测试 Go 应用程序的 TravisCI 配置

pointers - 在循环中重置指针

go - 如何在gcloud上部署golang应用

multithreading - 负载下降后线程会缠绕

postman 中未显示 Golang Rest api 数据

api - GO单元测试结构化REST API项目

google-app-engine - Golang lua-script 就像在 GAE 上运行

go - 并行循环

sql - 如何在 go-pg(带 Go 的 Postgres ORM)中查询嵌套结构中的子字段?