执行SQL查询
也可以直接执行一个SQL查询,即Select命令。在Postgres中支持原始SQL语句中使用 ` 和 ? 符号。
sql := "select * from userinfo"
results, err := engine.Query(sql)
当调用Query
时,第一个返回值results
为[]map[string][]byte
的形式。
执行SQL命令
也可以直接执行一个SQL命令,即执行Insert, Update, Delete 等操作。此时不管数据库是何种类型,都可以使用 ` 和 ? 符号。
sql = "update `userinfo` set username=? where id=?"
res, err := engine.Exec(sql, "xiaolun", 1)
查:
Get方法
查询单条数据使用Get
方法,在调用Get方法时需要传入一个对应结构体的指针,同时结构体中的非空field自动成为查询的条件和前面的方法条件组合在一起查询。
如:
1) 根据Id来获得单条数据:
user := new(User)
has, err := engine.Id(id).Get(user)
// 复合主键的获取方法
// has, errr := engine.Id(xorm.PK{1,2}).Get(user)
2) 根据Where来获得单条数据:
user := new(User)
has, err := engine.Where("name=?", "xlw").Get(user)
3) 根据user结构体中已有的非空数据来获得单条数据:
user := &User{Id:1}
has, err := engine.Get(user)
或者其它条件
user := &User{Name:"xlw"}
has, err := engine.Get(user)
返回的结果为两个参数,一个has
为该条记录是否存在,第二个参数err
为是否有错误。不管err是否为nil,has都有可能为true或者false。
Exist系列方法
判断某个记录是否存在可以使用Exist
, 相比Get
,Exist
性能更好。
例如:
has, err = testEngine.Where("name = ?", "test1").Exist(&RecordExist{})
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
has, err = testEngine.SQL("select * from record_exist where name = ?", "test1").Exist()
// select * from record_exist where name = ?
has, err = testEngine.Table("record_exist").Exist()
// SELECT * FROM record_exist LIMIT 1
has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist()
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
Find方法
查询多条数据使用Find
方法,Find方法的第一个参数为slice
的指针或Map
指针,即为查询后返回的结果,第二个参数可选,为查询的条件struct的指针。
1) 传入Slice用于返回数据
everyone := make([]Userinfo, 0)
err := engine.Find(&everyone)
pEveryOne := make([]*Userinfo, 0)
err := engine.Find(&pEveryOne)
2) 传入Map用户返回数据,map必须为map[int64]Userinfo
的形式,map的key为id,因此对于复合主键无法使用这种方式。
users := make(map[int64]Userinfo)
err := engine.Find(&users)
pUsers := make(map[int64]*Userinfo)
err := engine.Find(&pUsers)
3) 也可以加入各种条件
users := make([]Userinfo, 0)
err := engine.Where("age > ? or name = ?", 30, "xlw").Limit(20, 10).Find(&users)
4) 如果只选择单个字段,也可使用非结构体的Slice
var ints []int64
err := engine.Table("user").Cols("id").Find(&ints)
Count方法
统计数据使用Count
方法,Count方法的参数为struct的指针并且成为查询条件。
user := new(User)
total, err := engine.Where("id >?", 1).Count(user)
Rows方法
Rows方法和Iterate方法类似,提供逐条执行查询到的记录的方法,不过Rows更加灵活好用。
user := new(User)
rows, err := engine.Where("id >?", 1).Rows(user)
if err != nil {
}
defer rows.Close()
for rows.Next() {
err = rows.Scan(user)
//...
}
改:
- 插入不同表的一条或多条记录
user := new(User)
user.Name = "myname"
...
questions := make([]Question, 1)
questions[0].Content = "whywhywhwy?"
affected, err := engine.Insert(user, &questions)
软删除Deleted
Deleted可以让您不真正的删除数据,而是标记一个删除时间。使用此特性需要在xorm标记中使用deleted标记,如下所示进行标记,对应的字段必须为time.Time类型。
type User struct {
Id int64
Name string
DeletedAt time.Time `xorm:"deleted"`
}
在Delete()时,deleted标记的字段将会被自动更新为当前时间而不是去删除该条记录,如下所示:
var user User
engine.Id(1).Get(&user)
// SELECT * FROM user WHERE id = ?
engine.Id(1).Delete(&user)
// UPDATE user SET ..., deleted_at = ? WHERE id = ?
engine.Id(1).Get(&user)
// 再次调用Get,此时将返回false, nil,即记录不存在
engine.Id(1).Delete(&user)
// 再次调用删除会返回0, nil,即记录不存在
那么如果记录已经被标记为删除后,要真正的获得该条记录或者真正的删除该条记录,需要启用Unscoped,如下所示:
var user User
engine.Id(1).Unscoped().Get(&user)
// 此时将可以获得记录
engine.Id(1).Unscoped().Delete(&user)
// 此时将可以真正的删除记录