【发布时间】:2018-03-24 05:15:08
【问题描述】:
我的问题类似于How to create singleton DB class in GoLang,但我无法让它与单独的模型和服务包一起使用。
项目/lib/database/mysql.go:
package database
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
)
type Manager struct {
*gorm.DB
}
var Mgr *Manager
func init() {
dsn := MysqlConnectionString("parseTime=true")
tablePrefix := "demo"
var err error
gorm.DefaultTableNameHandler = func(db *gorm.DB, defaultTableName string) string {
return fmt.Sprintf("%v_%v", tablePrefix, defaultTableName)
}
db, err := gorm.Open("mysql", dsn)
if err != nil {
panic(err)
}
Mgr = &Manager{db}
}
project/lib/models/retailer_keys.go
package models
import (
"fmt"
"project/lib/database"
"time"
)
type RetailerKeysInterface interface {
RetailerKeys() ([]*RetailerKey, error)
}
type DB struct {
database.Manager
}
type RetailerKey struct {
Id int `json:"id"`
RetailerId int `json:"retailer_id"`
Key string `json:"key"`
Enabled *bool `json:"enabled"`
CreatedAt *time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
}
func (db *DB) RetailerKeys() ([]*RetailerKey, error) {
var keys []*RetailerKey
if err := db.Find(&keys).Error; err != nil {
return nil, err
}
return keys, nil
}
project/lib/services/retailer_keys.go
import (
"fmt"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/apigateway"
"gopkg.in/volatiletech/null.v6"
"project/lib/models"
"project/lib/services/api_keys"
)
func GetKeys() ([]*models.RetailerKey, error) {
var q models.RetailerKeysInterface
keys, err := q.RetailerKeys()
if err != nil {
return nil, err
}
return keys, nil
}
func CreateKey(id int) (models.RetailerKey, error) {
...
}
然后可以在我的主包中使用它,例如:
package main
import (
"context"
"encoding/json"
// "reflect"
"fmt"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
_ "project/lib/config"
"project/lib/services"
)
func Handler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
statusCode := 200
keys, err := services.GetKeys()
if err != nil {
statusCode = 400
}
body, _ := json.Marshal(keys)
return events.APIGatewayProxyResponse{
Body: string(body),
StatusCode: statusCode,
}, nil
}
...
我希望能够在我的模型中嵌入 Manager 类型的相关子集。
编辑: 根据 cmets 中的反馈编辑问题/代码。
这给了我一个错误:runtime error: invalid memory address or nil pointer dereference。
【问题讨论】:
-
根据引用的代码,错误是准确的;
DB没有Find方法。有什么问题? -
@Adrian 然后我如何访问模型包中的 *gorm.DB?
-
type Manager interface {}没有定义任何方法,将其嵌入DB不会神奇地揭示 gorm 的方法。您需要定义要在 Manager 上使用的 gorm 方法,或者不使用接口并将 gorm.DB 嵌入到您的数据库中。 -
尝试浏览这些:one、two、three、four。在这里你可以看到哪里出了问题:play.golang.org/p/yjwMLHToNP9 还要注意堆栈跟踪中的行号,它们会告诉你你到底在哪里犯了错误。
标签: go