gorm存指针数据_Gorm的高级用法

一、 钩子

钩子是一个在 插入 / 查询 / 更新 / 删除 之前或之后被调用的方法。

在一个模型中定义特殊的方法,它将会在插入,更新,查询,删除的时候被自动调用,如果任何的回调抛出错误,GORM 将会停止将要执行的操作并且回滚当前的改变。

// 开启事务

BeforeSave

BeforeCreate

// 连表前的保存

// 更新时间戳 `CreatedAt`, `UpdatedAt`

// 保存自己

// 重载哪些有默认值和空的字段

// 链表后的保存

AfterCreate

AfterSave

// 提交或回滚事务

Example:

func (u *User) BeforeSave() (err error) {

if u.IsValid() {

err = errors.New("can't save invalid data")

}

return

}

func (u *User) AfterCreate(scope *gorm.Scope) (err error) {

if u.ID == 1 {

scope.DB().Model(u).Update("role", "admin")

}

return

}

// 在 GORM 中的保存 / 删除 操作会默认进行事务处理,所以在事物中,所有的改变都是无效的,直到它被提交为止:

func (u *User) AfterCreate(tx *gorm.DB) (err error) {

tx.Model(u).Update("role", "admin")

return

}

更新对象

// 开启事务

BeforeSave

BeforeUpdate

// 链表前的保存

// 更新时间戳 `UpdatedAt`

// 保存自身

// 链表后的保存

AfterUpdate

AfterSave

// 提交或回滚的事务

func (u *User) BeforeUpdate() (err error) {

if u.readonly() {

err = errors.New("read only user")

}

return

}

// 在事务结束后,进行更新数据

func (u *User) AfterUpdate(tx *gorm.DB) (err error) {

if u.Confirmed {

tx.Model(&Address{}).Where("user_id = ?", u.ID).Update("verfied", true)

}

return

}

删除对象:可用于删除的钩子

// 开启事务

BeforeDelete

// 删除自身

AfterDelete

// 提交或回滚事务

// 在事务结束后进行更新数据

func (u *User) AfterDelete(tx *gorm.DB) (err error) {

if u.Confirmed {

tx.Model(&Address{}).Where("user_id = ?", u.ID).Update("invalid", false)

}

return

}

查询对象:可用于查询的钩子

// 从数据库中读取数据

// 加载之前 (急于加载)

AfterFind

func (u *User) AfterFind() (err error) {

if u.MemberShip == "" {

u.MemberShip = "user"

}

return

}

二、事务

GORM 默认在事务中执行单个 create, update, delete 操作,以确保数据库数据完整性。如果需要将多个 create, update, delete 当成一个原子性操作,Transaction 就是为了这个而创造的。

事务流程:

// 开启事务

tx := db.Begin()

// 在事务中执行一些数据库操作 (从这里开始使用 'tx',而不是 'db')

tx.Create(...)

// ...

// 发生错误回滚事务

tx.Rollback()

// 或者提交这个事务

tx.Commit()

三、运行原生SQL

执行原生SQL时不能使用链式调用其他方法

db.Exec("DROP TABLE users;")

db.Exec("UPDATE orders SET shipped_at=? WHERE id IN (?)", time.Now(), []int64{11,22,33})

// Scan

type Result struct {

Name string

Age int

}

var result Result

db.Raw("SELECT name, age FROM users WHERE name = ?", 3).Scan(&result)

使用 *sql.Row 或者 *sql.Rows 获得查询结果

row := db.Table("users").Where("name = ?", "jinzhu").Select("name, age").Row() // (*sql.Row)

row.Scan(&name, &age)

rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error)

defer rows.Close()

for rows.Next() {

...

rows.Scan(&name, &age, &email)

...

}

// 原生SQL

rows, err := db.Raw("select name, age, email from users where name = ?", "jinzhu").Rows() // (*sql.Rows, error)

defer rows.Close()

for rows.Next() {

...

rows.Scan(&name, &age, &email)

...

}

扫描 sql.Rows 数据到模型

rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error)

defer rows.Close()

for rows.Next() {

var user User

// ScanRows 扫描一行到 user 模型

db.ScanRows(rows, &user)

// do something

}

四、数据库接口

GORM 提供了从当前的 *gorm.DB 连接中返回通用的数据库接口的方法 DB *sql.DB 。

// 获取通用数据库对象 sql.DB 来使用他的 db.DB() 方法

// Ping

db.DB().Ping()

// 连接池

// SetMaxIdleConns 设置空闲连接池中的最大连接数。

db.DB().SetMaxIdleConns(10)

// SetMaxOpenConns 设置数据库连接最大打开数。

db.DB().SetMaxOpenConns(100)

// SetConnMaxLifetime 设置可重用连接的最长时间

db.DB().SetConnMaxLifetime(time.Hour)

五、自定义Loggor(感觉没啥用)

// 开启 Logger, 以展示详细的日志

db.LogMode(true)

// 关闭 Logger, 不再展示任何日志,即使是错误日志

db.LogMode(false)

// 对某个操作展示详细的日志,用来排查该操作的问题

db.Debug().Where("name = ?", "jinzhu").First(&User{})

例如,使用  Revel 的 Logger 作为 GORM 的输出

db.SetLogger(gorm.Logger{revel.TRACE})

// 使用 os.Stdout 作为输出

db.SetLogger(log.New(os.Stdout, "\r\n", 0))

你可能感兴趣的:(gorm存指针数据)