xorm使用小结 xorm是一个go的orm框架。用起来还挺难用的。 资料:https://www.kancloud.cn/kancloud/xorm-manual-zh-cn/56013 ## 自动根据数据库database_name创建模型: 使用xorm需要先有一个模型struct,比如这个: ``` type User struct { Id int64 `json:"f_id" xorm:"not null pk autoincr INT(11)"` Name string `json:"f_name" xorm:"not null comment('name') VARCHAR(64)"` } ``` 这样复杂的struct,自然有工具可以自动生成。 ### 使用网址生成 我自己做了一个:https://www.superpig.win/sql2go/xorm 传入create 表命令,即可生成相关代码 ### 手工使用工具生成,不推荐 首先,确保`/home/USERNAME/goxorm`文件夹下有这两个文件:  config ``` lang=go genJson=1 prefix=cos_ ``` struct.go.tpl ``` package {{.Models}} {{$ilen := len .Imports}} {{if gt $ilen 0}} import ( {{range .Imports}}"{{.}}"{{end}} ) {{end}} {{range .Tables}} type {{Mapper .Name}} struct { {{$table := .}} {{range .ColumnsSeq}}{{$col := $table.GetColumn .}} {{Mapper $col.Name}} {{Type $col}} {{Tag $table $col}} {{end}} } {{end}} ``` 把xorm工具(https://github.com/go-xorm/cmd/blob/master/README.md ) 可执行放到$PATH下面,然后执行: ``` cd /home/USERNAME/goxorm xorm reverse mysql "root:123456@tcp(127.0.0.1:3306)/database_name?charset=utf8" /home/USERNAME/goxorm ``` ## 创建引擎 要使用xorm,在项目中,先初始化一个engine,设置为全局即可 ``` import( _ "github.com/go-sql-driver/mysql" "xorm.io/xorm" xlog "xorm.io/xorm/log" ) var GlobalEngine *xorm.Engine func InitMysql(cfg *atomic.Pointer[config.AppConfig]) error { var err error mysqlCfg := cfg.Load().Mysql GlobalEngine, err := xorm.NewEngine("mysql", "root:123456@tcp(10.10.30.99:3306)/test?charset=utf8") if err != nil { return err } GlobalEngine.SetConnMaxLifetime(time.Hour) GlobalEngine.SetMaxIdleConns(25) GlobalEngine.SetMaxOpenConns(30) GlobalEngine.ShowSQL(true) GlobalEngine.Logger().SetLevel(xlog.LOG_ERR) return nil } ``` ## 增 ``` u := &User{ Name: "aaa", } // 可插入多条engine.Insert(u1,u2) affecte, err := engine.Insert(u) if err != nil { fmt.Println("insert is failed,err:", err) } fmt.Println("affect=", affecte, u.Id) 如果id是自增的,那insert后u.Id会自动变成自增的id。就是这么神奇。 ``` ## 删 ``` res, err := engine.Exec("delete from t_user where f_id=?", s.FId) if err != nil { return nil, err } affected, _ := res.RowsAffected() // 使用api user := new(User) affected, err := engine.Id(id).Delete(user) ``` ## 改 ``` // update t_user set Name="haha" where f_id=123; s := &User{Name:"haha"} affected, err = engine.Update(s, &User{Id: 123}) //如果是按主键更新,还可以 s := &User{Name:"haha"} _, err := engine.Id(123).Update(s) // 更新特定、所有字段 engine.Cols("age", "name").Update(&user) engine.AllCols().Id(1).Update(s) ``` ## 查 按sql ``` // 执行完后,ret被神奇的赋值了 var ret []*User err:=engine.SQL("select * from t_user where f_name=?;", userName).Find(&ret) ``` 使用api ``` // where users := make([]User, 0) err := engine.Where("f_id > ? or f_name=?)", 30, "pig").Limit(10, 10).Find(&users) // 用查询条件结构(各属性and关系) user := &User{Name:"xlw"} // 直接就地赋值给user has, err := engine.Get(user) // select * from user where f_name='xlw' limit 1 // 查询数组,find的第二个可选参数是查询条件bean var users []*User has, err := engine.Find(&users, user) // 如果传入的是map,则会返回key为id的数据 users := make(map[int64]User) err := engine.Find(&users, user) // Iterate,可以对查询的结果进行遍历,感觉没啥用:) err := engine.Where("f_name=?)", "xlw").Iterate(new(User), func(i int, bean interface{})error{ user := bean.(*User) //do somthing use i and user }) ``` 查询数量 ``` // count user := new(User) total, err := engine.Where("f_id >?", 1).Count(user) ``` join查询 ``` // join 直接新建一个新结构体,把原有的标记为extends type UserGroup struct { User `xorm:"extends"` Group `xorm:"extends"` } users := make([]UserGroup, 0) engine.Table("user").Join("left", "group", "group.id = user.group_id").Where("user.name=?", name).Find(&users) ``` 动态构造查询条件,假设传入一系列的结构化查询条件,根据这些条件生成sql ``` import "xorm.io/builder" cond := builder.In("val", vals...).And(builder.Eq{"childtype": ttype}) l := make([]*Items, 0) // 查询distinct err := GlobalEngine.Distinct("subid").Where(cond).Find(&l) if err != nil { return nil, err } // or 返回字典 dbRets, err := model.GlobalEngine.Table("tableName").Where(cond).Query() ``` ## 事务 ``` sess:= engine.NewSession() defer sess.Close() if err := sess.Begin() ; err != nil { return errors.New("fail to session begin") } if _, err := sess.Id(id1).Update(account_1) ; err != nil { sess.Rollback() return errors.New("fail to update 1") } err = sess.Commit() if err != nil { return } ``` 来自 大脸猫 写于 2019-06-21 14:41 -- 更新于2024-04-07 15:27 -- 0 条评论