原文转载自:Go 每日一库之 xorm
Get
Get 用于查询单条数据:
type User struct {
Id int64
Name string
Salt string
Age int
Passwd string `xorm:"varchar(200)"`
Created time.Time `xorm:"created"`
Updated time.Time `xorm:"updated"`
}
func main() {
engine, _ := xorm.NewEngine("mysql", "root:12345@/test?charset=utf8")
user1 := &User{}
has, _ := engine.ID(1).Get(user1)
if has {
fmt.Printf("user1:%v\n", user1)
}
user2 := &User{}
has, _ = engine.Where("name=?", "dj").Get(user2)
if has {
fmt.Printf("user2:%v\n", user2)
}
user3 := &User{Id: 5}
has, _ = engine.Get(user3)
if has {
fmt.Printf("user3:%v\n", user3)
}
user4 := &User{Name: "pipi"}
has, _ = engine.Get(user4)
if has {
fmt.Printf("user4:%v\n", user4)
}
}
上面演示了 3 种使用Get()的方式:
- 使用主键
engine.ID(1)查询主键(即id)为 1 的用户。 - 使用条件语句:
engine.Where("name=?", "dj")查询name = "dj"的用户。 - 使用对象中的非空字段:
user3设置了Id字段为 5,engine.Get(user3)查询id = 5的用户;user4设置了字段Name为"pipi",engine.Get(user4)查询name = "pipi"的用户。
查询条件的使用不区分调用顺序,但是必须在Get()方法之前调用。后面介绍的查询,统计方法也是如此,可以在调用实际的方法前添加一些过滤条件。
除此之外xorm支持只返回指定的列(xorm.Cols())或忽略特定的列(xorm.Omit()):
func main() {
engine, _ := xorm.NewEngine("mysql", "root:12345@/test?charset=utf8")
user1 := &User{}
engine.ID(1).Cols("id", "name", "age").Get(user1)
fmt.Printf("user1:%v\n", user1)
user2 := &User{Name: "pipi"}
engine.Omit("created", "updated").Get(user2)
fmt.Printf("user2:%v\n", user2)
}
第一个查询使用Cols()方法指定只返回 id、name、age 这 3 列,第二个查询使用Omit()方法忽略列 created 和 updated。
Exist
Exist()方法查询符合条件的记录是否存在,它的返回与 Get() 方法一致,都是 (bool, error)。
不同之处在于Get()会将查询得到的字段赋值给传入的对象。
Find
Get()方法只能返回单条记录,其生成的 SQL 语句总是有LIMIT 1。Find()方法返回所有符合条件的记录,Find()需要传入对象切片的指针或 map 的指针:
func main() {
engine, _ := xorm.NewEngine("mysql", "root:12345@/test?charset=utf8")
slcUsers:= make([]User, 1)
engine.Where("age > ? and age < ?", 12, 30).Find(&slcUsers)
fmt.Println("users whose age between [12,30]:", slcUsers)
mapUsers := make(map[int64]User)
engine.Where("length(name) = ?", 3).Find(&mapUsers)
fmt.Println("users whose has name of length 3:", mapUsers)
}
map的键为主键,所以如果表为复合主键就不能使用这种方式了。
Iterate
与Find()一样,Iterate()也是找到满足条件的所有记录,只不过传入了一个回调去处理每条记录:
func main() {
engine, _ := xorm.NewEngine("mysql", "root:12345@/test?charset=utf8")
engine.Where("age > ? and age < ?", 12, 30).Iterate(&User{}, func(i int, bean interface{}) error {
fmt.Printf("user%d:%v\n", i, bean.(*User))
return nil
})
}
如果回调返回一个非nil的错误,后面的记录就不会再处理了。
Rows
Rows()方法与Iterate()类似,不过返回一个Rows对象由我们自己迭代,更加灵活:
func main() {
engine, _ := xorm.NewEngine("mysql", "root:12345@/test?charset=utf8")
rows, _ := engine.Where("age > ? and age < ?", 12, 30).Rows(&User{})
defer rows.Close()
u := &User{}
for rows.Next() {
rows.Scan(u)
fmt.Println(u)
}
}
Count
Sum
插入
使用engine.Insert()方法,可以插入单条数据,也可以批量插入多条数据:
func main() {
engine, _ := xorm.NewEngine("mysql", "root:12345@/test?charset=utf8")
user := &User{Name: "lzy", Age: 50}
affected, _ := engine.Insert(user)
fmt.Printf("%d records inserted, user.id:%d\n", affected, user.Id)
users := make([]*User, 2)
users[0] = &User{Name: "xhq", Age: 41}
users[1] = &User{Name: "lhy", Age: 12}
affected, _ = engine.Insert(&users)
fmt.Printf("%d records inserted, id1:%d, id2:%d", affected, users[0].Id, users[1].Id)
}
更新
注意:传入结构体指针的情况,xorm只会更新非空的字段,这里容易制造Bug。
如果一定要更新空字段,需要使用Cols()方法显示指定更新的列。使用Cols()方法指定列后,即使字段为空也会更新:
func main() {
engine, _ := xorm.NewEngine("mysql", "root:12345@/test?charset=utf8")
engine.ID(1).Update(&User{Name: "ldj"})
engine.ID(1).Cols("name", "age").Update(&User{Name: "dj"})
}
第一个Update()方法只会更新name字段,其他空字段不更新。第二个Update()方法会更新name和age两个字段,age被更新为 0。
删除
直接调用engine.Delete()删除符合条件的记录,返回删除的条目数量:
func main() {
engine, _ := xorm.NewEngine("mysql", "root:12345@/test?charset=utf8")
affected, _ := engine.Where("name = ?", "lzy").Delete(&User{})
fmt.Printf("%d records deleted", affected)
}
执行原始SQL
除了上面提供的方法外,xorm还可以执行原始的 SQL 语句:
func main() {
engine, _ := xorm.NewEngine("mysql", "root:12345@/test?charset=utf8")
querySql := "select * from user limit 1"
reuslts, _ := engine.Query(querySql)
for _, record := range reuslts {
for key, val := range record {
fmt.Println(key, string(val))
}
}
updateSql := "update `user` set name=? where id=?"
res, _ := engine.Exec(updateSql, "ldj", 1)
fmt.Println(res.RowsAffected())
}
排错
了便于排查可能出现的问题,xorm提供了 ShowSQL() 方法设置将执行的 SQL 同时在控制台中输出:
func main() {
engine, _ := xorm.NewEngine("mysql", "root:12345@/test?charset=utf8")
engine.ShowSQL(true)
user := &User{}
engine.ID(1).Omit("created", "updated").Get(user)
fmt.Printf("user:%v\n", user)
}
如果调试信息都输出到控制台并不利于我们查询,xorm可以设置日志选项,将日志输出到文件中:
func main() {
engine, _ := xorm.NewEngine("mysql", "root:12345@/test?charset=utf8")
f, err := os.Create("sql.log")
if err != nil {
panic(err)
}
engine.SetLogger(log.NewSimpleLogger(f))
engine.Logger().SetLevel(log.LOG_DEBUG)
engine.ShowSQL(true)
user := &User{}
engine.ID(1).Omit("created", "updated").Get(user)
fmt.Printf("user:%v\n", user)
}
log.NewSimpleLogger(f)是xorm的子包xorm.io/xorm/log提供的简单日志封装,而非标准库log。





网友评论