说明
- XORM文档
-
xorm-plus,xorm的增强版本,支持嵌套式事务
- 使用的是sqlite数据库
- 语句
orm.ShowSQL(true)
是打开xorm的sql日志
- 语句
err = orm.Sync2(new(User))
是同步User的字段信息到数据库的schema
- 重点在于defer 语句,defer 语句是用来延迟执行函数的,而且延迟发生在调用函数 return 之后,被 defer 修饰的函数在 return 之后执行,这个时机点正好可以捕获函数抛出的 panic,因而 defer 的另一个重要用途就是执行 recover。recover 只有在 defer 中使用才更有意义,如果在其他地方使用,由于 program 已经调用结束而提前返回而无法有效捕捉错误。defer 的作用就是把关键字之后的函数执行压入一个栈中延迟执行,多个 defer 的执行顺序是后进先出 LIFO(Last In First Out后进先出),此处在defer中判断是否有抛出panic,如果抛出错误,执行回滚,如果函数返回错误,也执行回滚,否则执行commit操作
示例代码
import (
"fmt"
"github.com/go-xorm/xorm"
_ "github.com/mattn/go-sqlite3"
"time"
)
// User is our user table structure.
type User struct {
ID int64 // auto-increment by-default by xorm
Version string `xorm:"varchar(200)"`
Salt string
Username string
Password string `xorm:"varchar(200)"`
Languages string `xorm:"varchar(200)"`
CreatedAt time.Time `xorm:"created"`
UpdatedAt time.Time `xorm:"updated"`
}
func TestXORM() {
orm, err := xorm.NewEngine("sqlite3", "./test.db")
if err != nil {
panic(err)
}
orm.ShowSQL(true)
err = orm.Sync2(new(User))
session := orm.NewSession()
addUser(session)
}
type ORMOperation func(session *xorm.Session) error
func Transaction(session *xorm.Session, f ORMOperation) (err error) {
err = session.Begin()
if err != nil {
return
}
defer func() {
if p := recover(); p != nil {
fmt.Printf("recover rollback:%s\r\n",p)
session.Rollback()
panic(p) // re-throw panic after Rollback
} else if err != nil {
fmt.Printf("error rollback:%s\r\n",err)
session.Rollback() // err is non-nil; don't change it
} else {
err = session.Commit() // err is nil; if Commit returns error update err
}
}()
err = f(session)
return err
}
func addUser(session *xorm.Session) error {
//Transaction 的 f 参数类型为 ORMOperation,
// addUser 和 ORMOperation 函数类型相同的参数和返回值,
// 因此可以将 addUser 函数作为参数传入 Transaction 函数中。
return Transaction(session, func(session *xorm.Session) error {
if _,error := session.Insert(User{ID:5,Version:"abc"}); error != nil{
return error
}
if _,error := session.Insert(User{ID:6,Version:"bcd"}); error != nil{
return error
}
if _,error := session.Insert(User{ID:4,Version:"cde"}); error != nil{
return error
}
return nil
})
}