Mysql 如何在Revel Controller中访问Gorm?

Mysql 如何在Revel Controller中访问Gorm?,mysql,go,go-gorm,revel,Mysql,Go,Go Gorm,Revel,让我先说这是我在围棋中玩的头几天 我尝试将Revel框架与Gorm一起使用,如下所示: package controllers import "github.com/revel/revel" func init() { revel.OnAppStart(InitDB) // maybe some other init things } app/controllers/gorm.go package controllers import ( "fmt" "g

让我先说这是我在围棋中玩的头几天

我尝试将Revel框架与Gorm一起使用,如下所示:

package controllers

import "github.com/revel/revel"

func init() {
    revel.OnAppStart(InitDB)
    // maybe some other init things
}
app/controllers/gorm.go

package controllers

import (
    "fmt"
    "go-testapp/app/models"

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

var DB gorm.DB

func InitDB() {
    var err error
    DB, err = gorm.Open("mysql", "root:@/go-testapp?charset=utf8&parseTime=True")
    if err != nil {
        panic(err)
    }
    DB.LogMode(true)
    DB.AutoMigrate(models.User{})
}

type GormController struct {
    *revel.Controller
    DB *gorm.DB
}
package controllers

import (
    "fmt"
    "go-bingo/app/models"

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

type App struct {
    GormController
}

func (c App) Index() revel.Result {
    user := models.User{Name: "Jinzhu", Age: 18}

    fmt.Println(c.DB)
    c.DB.NewRecord(user)

    c.DB.Create(&user)

    return c.RenderJson(user)
}
app/controller/app.go

package controllers

import (
    "fmt"
    "go-testapp/app/models"

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

var DB gorm.DB

func InitDB() {
    var err error
    DB, err = gorm.Open("mysql", "root:@/go-testapp?charset=utf8&parseTime=True")
    if err != nil {
        panic(err)
    }
    DB.LogMode(true)
    DB.AutoMigrate(models.User{})
}

type GormController struct {
    *revel.Controller
    DB *gorm.DB
}
package controllers

import (
    "fmt"
    "go-bingo/app/models"

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

type App struct {
    GormController
}

func (c App) Index() revel.Result {
    user := models.User{Name: "Jinzhu", Age: 18}

    fmt.Println(c.DB)
    c.DB.NewRecord(user)

    c.DB.Create(&user)

    return c.RenderJson(user)
}
运行后,会导致:

运行时错误:第19行
c.DB.NewRecord(用户)

它使用automigrate成功地创建了数据表,但我不知道应该如何在控制器中使用Gorm


有没有正确的提示?

您的错误是由于您没有初始化c.DB数据库变量而导致的,它仍然为零

在controllers/init.go文件中,确保您正在调用revel.OnAppStart(InitDB)。它应该是这样的:

package controllers

import "github.com/revel/revel"

func init() {
    revel.OnAppStart(InitDB)
    // maybe some other init things
}
重要提示 它只是一个替代品。它也有一些起源的陷阱。这个答案可以作为原答案的替代品。但这并不能解决陷阱

请看一看这个非答案的评论,它解决了陷阱

我建议您使用@MaxGabriel的解决方案来保护您的应用程序免受某些类型的慢速DDoS攻击。并降低(在某些情况下)DB压力

原始答案 ,您必须调用
InitDB
内部的
init
函数(进入
controllers
包)

这里的完整示例(太多):

/app
/控制器
app.go
gorm.go
开始
/模型
user.go
[...]
user.go

//模型/user.go
包装模型
导入“时间”//如果需要/想要
键入用户结构{//示例用户字段
Id int64
名称字符串
加密密码[]字节
密码字符串`sql:“-”`
时间,时间
时间到了,时间到了
DeletedAt time.time//用于软删除
}
gorm.go

//控制器/gorm.go
包控制器
进口(
“github.com/jinju/gorm”
_“github.com/lib/pq”//my-example for postgres
//狂欢的简称
r“github.com/revel/revel”
//你的应用程序名称
“yourappname/app/models”
“数据库/sql”
)
//类型:带有“*gorm.DB”的revel控制器`
//c.Txn将保留'Gdb*gorm.DB`
类型GormController结构{
*r、 控制器
Txn*gorm.DB
}
//它可以用于工作
变量Gdb*gorm.DB
//初始化数据库
func InitDB(){
变量错误
//开放数据库
Gdb,err=gorm.Open(“postgres”,“user=uname dbname=udbname sslmode=disable password=supersecret”)
如果错误!=零{
r、 错误。Println(“致命”,错误)
恐慌(错误)
}
Gdb.AutoMigrate(&models.User{})
//如果需要,请使用唯一索引
//Gdb.Model(&models.User{}).AddUniqueIndex(“idx_User_name”,“name”)
}
//交易
//此方法在每次事务之前填充c.Txn
func(c*GormController)Begin()r.结果{
txn:=Gdb.Begin()
如果txn.错误!=nil{
死机(txn.错误)
}
c、 Txn=Txn
归零
}
//此方法在每次事务处理后清除c.Txn
func(c*GormController)Commit()r.结果{
如果c.Txn==nil{
归零
}
c、 Txn.Commit()
如果err:=c.Txn.Error;err!=nil&&err!=sql.ErrTxDone{
恐慌(错误)
}
c、 Txn=零
归零
}
//此方法也会在每次事务处理后清除c.Txn
func(c*GormController)回滚()r.结果{
如果c.Txn==nil{
归零
}
c、 Txn.Rollback()
如果err:=c.Txn.Error;err!=nil&&err!=sql.ErrTxDone{
恐慌(错误)
}
c、 Txn=零
归零
}
应用程序运行

包控制器
进口(
“github.com/revel/revel”
“yourappname/app/models”
)
类型App struct{
戈尔姆控制器
}
函数(c应用程序)索引()相关结果{
用户:=模型。用户{Name:“jinhup”}
c、 Txn.NewRecord(用户)
c、 Txn.Create(&user)
返回c.RenderJSON(用户)
}
init.go

包控制器
导入“github.com/revel/revel”
func init(){
revel.OnAppStart(InitDB)//在之前调用InitDB函数
revel.InterceptMethod((*GormController.Begin,revel.BEFORE)
revel.InterceptMethod((*GormController.Commit,revel.AFTER)
revel.InterceptMethod((*GormController.Rollback,revel.FINALLY)
}
正如你所看到的,这就像Revel为GORM修改了预订一样

对我来说很好。结果:

{
“Id”:5,
“姓名”:“金珠”,
“EncryptedPassword”:空,
“密码”:“,
“CreatedAt”:“2014-09-22T17:55:14.828661062+04:00”,
“更新日期”:“2014-09-22T17:55:14.828661062+04:00”,
“删除数据”:“0001-01-01T00:00:00Z”
}

或者您需要传入指向AutoMigrate的指针

 DB.AutoMigrate(&models.User{})

根据@IvanBlack的建议,这个答案来自他的答案。他的版本是Revel示例代码的直接翻译,但是我们发现了这个答案修复的原始代码中的一些问题。它的主要变化是:

  • 整个HTTP请求不再由数据库事务包装。包装整个HTTP请求会使事务保持打开状态的时间远远超过必要的时间,这可能会导致许多问题:

    • 您的事务将在数据库上持有锁,许多持有锁的事务可能会导致死锁
    • 使用了更多的数据库资源
    • 如果您的HTTP请求主要不受SQL数据库访问的限制,那么这些问题将被放大。例如,如果您的HTTP请求在发出外部HTTP请求或访问另一个数据库时阻塞30秒,则这些服务的速度减慢可能会影响您的SQL数据库
  • 由于在HTTP请求结束时不再自动检查事务是否存在错误,因此在插入数据库时会立即检查错误。这也更正确:想象一下