xorm是一个go的orm框架。用起来还挺难用的。
使用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,自然有工具可以自动生成。
首先,确保/home/yzh/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/yzh/goxorm
xorm reverse mysql "root:123456@tcp(127.0.0.1:3306)/database_name?charset=utf8" /home/yzh/goxorm
为了方便,我把xorm_linux给提取出来了:
要使用xorm,在项目中,初始化一个engine就行了
engine, err := xorm.NewEngine("mysql", "root:123456@tcp(10.10.30.99:3306)/test?charset=utf8")
if err != nil {
fmt.Println("connect mysql is failed, err:", err)
}
engine.SetConnMaxLifetime(time.Hour)
engine.SetMaxIdleConns(mysql.MaxIdleConn)
engine.SetMaxOpenConns(mysql.MaxConn)
engine.ShowSQL(true)
engine.ShowExecTime(true)
engine.Logger().SetLevel(core.LOG_ERR)
return engine
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)
// 按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"}
// 查询单个 select * from user where f_name='xlw'
// 直接就地赋值给user
has, err := engine.Get(user)
// 查询数组,find的第二个可选参数是查询条件bean
var users []*User
has, err := engine.Find(&users, user)
// 如果传入的是map,则会返回key为id的数据
users := make(map[int64]Userinfo)
err := engine.Find(&users, user)
// iter,可以对查询的结果进行遍历,感觉没啥用:)
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 直接新建一个新结构体,把原有的标记为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)
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
}