Wego Web Framework | GitHub 开发文档 开发社区
快速入门
Web模块
ORM模块
其他模块

会话

worm提供了Session方法用于创建带配置的会话。使用会话可以共用一组配置,例如:开启SQL预编译,或者是SQL日志输出配置。另外若要开启事务,则必须创建一个会话。

会话应当只用于一个go routine中, 通常在一个HTTP处理器中创建并使用会话。例如:


func AddOrder(c *wego.WebContext) {
	session := worm.NewSession()
	session.ShowLog(true)

	var order dao.Order
	order.Create_time = time.Now().Unix()
    //.....

	var err error
	order.Id, err = dbs.Model(&order).Insert()
	if err != nil {
		log.Error(err)
		c.AbortWithText(510, err.Error())
		return
	}

	c.WriteTextF(200, "%d", order.Id)
}

事务处理

当使用事务处理时,需要创建 Session对象,并开启数据库事务。在进行事务处理时,在事务中可以混用Struct映射、原生SQL以及SQLBuilder来访问数据库:


func demoTxCommit() {
	tx := worm.NewSession()
	tx.TxBegin()

	var user = User{Name:"name1", Age: 21, Created: time.Now()}
	id, err := tx.Model(&user).Insert()
	if err != nil{
		tx.TxRollback()
		return
	}

	_, err = tx.Table("users").Value("age", 20).Value("name", "zhangsan").Where("id=?", id).Update()
	if err != nil{
		tx.TxRollback()
		return
	}

	_, err = tx.SQL("delete from users where id=?", id).Exec()
	if err != nil{
		tx.TxRollback()
		return
	}

	tx.TxCommit()
}

使用SQL语句预编译

worm支持SQL语句的预编译,使用SQL语句预编译可以提升数据库访问的效率。在worm中可以通过三种方式开启SQL语句预编译:全局开启、会话中开启、语句中开启。


func main2() {
	dbcnn, err := initMySql("account:pwd@tcp(127.0.0.1:3306)/db?charset=utf8&parseTime=True")
	if err != nil {
		log.Error(err)
	}
	defer dbcnn.Close()
	err = worm.InitMysql(dbcnn)
	if err != nil {
		log.Error(err)
		return
	}
	worm.ShowSqlLog(true)
	//开启SQL语句预编译
	worm.UsePrepare(true)
	//设置预编译stmt缓存的最大数量
	worm.SetMaxStmtCacheNum(1000)
}

func demoPrepareSession() {
	session := worm.NewSession()
	session.UsePrepare(true)

	var user = User{Name:"name1", Age: 21, Created: time.Now()}
	id, err := worm.Model(&user).Insert()
	if err != nil{
		log.Error(err)
		return
	}

	_, err = worm.Model(&User{}).ID(id).Delete()
	if err != nil{
		log.Error(err)
		return
	}
}

func demoModelPrepare() {
	var user = User{Name:"name1", Age: 21, Created: time.Now()}
	_, err := worm.Model(&user).UsePrepare(true).Select("name", "age").ID(1).Update()
	if err != nil{
		log.Error(err)
		return
	}
}

钩子

钩子是在创建、查询、更新、删除等操作之前、之后调用的函数。如果您为模型定义了指定的钩子,它会在创建、更新、查询、删除时自动被调用。worm提供了以下钩子:


BeforeInsert(ctx context.Context)
AfterInsert(ctx context.Context)
BeforeUpdate(ctx context.Context)
AfterUpdate(ctx context.Context)
BeforeDelete(ctx context.Context)
AfterDelete(ctx context.Context)
BeforeQuery(ctx context.Context)
AfterQuery(ctx context.Context)

以下代码时添加了BeforeQuery钩子以及AfterQuery钩子的实体类:


type User struct {
	Id          int64   	`db:"id;autoincr"`
	Name        string  	`db:"name"`
	Age         int64   	`db:"age"`
	Passwd      string  	`db:"passwd"`
	Created     time.Time	`db:"created;n_update"`
}
func (ent *User) TableName() string {
	return "user"
}
func (ent *User)BeforeQuery(ctx context.Context) {
	fmt.Println("User.BeforeQuery")
	if ctx != nil {
		fmt.Println(ctx.Value("test_key"))
	}
}
func (ent *User)AfterQuery(ctx context.Context) {
	fmt.Println("User.AfterQuery")
	if ctx != nil {
		fmt.Println(ctx.Value("test_key"))
	}
}

输出SQL日志

worm缺省开启了SQL日志的输出,SQL日志的输出可以让您定位sql语句中的bug,也可以通过SQL日志来获取sql语句执行的性能。以下是SQL日志的例子:


[SQL] insert into user set name='NameVo',age=31
[RET] DB: time=36.202ms insertId=273
[SQL] update user set name='NameVo2',age=32 where id=273
[RET] DB: time=22.935ms affected=1
[SQL] select id,name,age from user where id=273 limit 1
[RET] DB: time=52.792ms
[SQL] select id,name,age from user where id>0
[RET] DB: time=19.891ms

说明:

sql语句:sql语句会转换为便于阅读的形式。

DB/TX:用于说明没有开启事务。

time:是执行sql语句的时间。

若不需要显示SQL日志, 您可以关闭日志的显示:


worm.ShowSqlLog(false)

自定义日志的输出

若您希望使用自定义的日志记录器来输出日志,您可以实现SQL日志回调函数,SQL日志回调函数的定义如下:


type SqlPrintCB func(ctx *LogContex)

例如:


func print_sql_log(ctx *worm.LogContex) {
	log.Println(ctx.GetPrintSQL())
	log.Println(ctx.GetPrintResult())
}

另外需要为worm开启SQL日志的输出,以及指定SQL日志回调函数:


worm.ShowSqlLog(true)
worm.SetSqlLogCB(print_sql_log)