01
介绍
beego ORM 是一个强大的 Go 语言 ORM 框架。她的灵感主要来自
Django ORM 和 SQLAlchemy。
已支持的数据库驱动有MySQL、PostgreSQL 和 Sqlite3。
beego v2.x 和 beego v1.x 在 ORM 上的区别是,beego v2.x 的 ORM 对象被设计为无状态的,它是线程安全的,建议大家在使用时,一个数据库只对应一个 ORM 对象。
本文全篇都是以 MySQL 为例。
关于 beego ORM 的安装和注册,已在「Golang 语言 Web 框架 beego v2 之写操作」中介绍,本文不再赘述。
02
普通查询
beego ORM 提供了两个普通查询的方法,分别是 Read 和 ReadOrCreate。
Read 方法默认把主键作为查询条件,也可以指定字段作为查询条件,如果指定字段作为查询条件,需要在 Read 方法的第二个参数中传入指定字段的名称。
示例代码:
Read 方法,主键查询
func (u *UserController) Read() { o := orm.NewOrm() user := &models.User{ Id: 2, } err := o.Read(user) if err != nil { log.Fatalln(err.Error()) return } fmt.Printf("user:%+v\n", user) }
Read 方法,指定字段查询
func (u *UserController) Read() { o := orm.NewOrm() user := &models.User{ Name: "Lucy", } err := o.Read(user, "Name") if err != nil { log.Fatalln(err.Error()) return } fmt.Printf("user:%+v\n", user) }
ReadOrCreate 方法默认必须传入一个参数作为条件字段,同时支持多个参数作为条件字段。根据条件字段从数据库中读取行,如果不存在,就插入一行。
ReadOrCreate 方法返回三个值,分别为一个 bool 类型,代表是否新插入一行;一个 int64 类型,代表查询对象(或新插入)的 Id;和一个 error 类型的错误。
示例代码:
ReadOrCreate 方法
func (u *UserController) Read() { o := orm.NewOrm() user := &models.User{ Name: "Alan", Age: 37, } created, id, err := o.ReadOrCreate(user,"Name", "Age") if err != nil { log.Fatalln(err.Error()) return } fmt.Printf("Created:%t,id:%d\n", created, id) fmt.Printf("user:%+v\n", user) }
03
高级查询
beego ORM 高级查询是通过获取一个 QuerySeter 对象,使用 QuerySeter 对象的方法实现高级查询。
QuerySeter 接口包含的方法:
type QuerySeter interface { Filter(string, ...interface{}) QuerySeter FilterRaw(string, string) QuerySeter Exclude(string, ...interface{}) QuerySeter SetCond(*Condition) QuerySeter GetCond() *Condition Limit(limit interface{}, args ...interface{}) QuerySeter Offset(offset interface{}) QuerySeter GroupBy(exprs ...string) QuerySeter OrderBy(exprs ...string) QuerySeter ForceIndex(indexes ...string) QuerySeter UseIndex(indexes ...string) QuerySeter IgnoreIndex(indexes ...string) QuerySeter RelatedSel(params ...interface{}) QuerySeter Distinct() QuerySeter ForUpdate() QuerySeter Count() (int64, error) Exist() bool Update(values Params) (int64, error) Delete() (int64, error) PrepareInsert() (Inserter, error) All(container interface{}, cols ...string) (int64, error) One(container interface{}, cols ...string) error Values(results *[]Params, exprs ...string) (int64, error) ValuesList(results *[]ParamsList, exprs ...string) (int64, error) ValuesFlat(result *ParamsList, expr string) (int64, error) RowsToMap(result *Params, keyCol string, valueCol string) (int64, error) RowsToStruct(ptrStruct interface{}, keyCol string, valueCol string) (int64, error) }
QuerySeter 对象
在介绍 QuerySeter 对象的方法之前,先给大家介绍如何获取一个 QuerySeter 对象,获取一个 QuerySeter 对象有三种方式,第一种是调用 ormer 的QueryTable 方法,参数传入一个 string 类型的表名;第二种是调用 ormer 的QueryTable 方法,参数传入一个结构体的地址;第三种是调用 ormer 的QueryTable 方法,参数传入一个指针类型的结构体;
示例代码:
var user models.User err := o.QueryTable("beego_user").One(&user) err = o.QueryTable(&user).One(&user) err = o.QueryTable(new(models.User)).One(&user)
本小节我们主要介绍一下 One 方法、All 方法和 Count 方法。
One 方法
One 方法返回单条记录,默认情况下,返回主键升序的第一条记录。如果指定查询条件,则返回符合查询条件的一条记录,如果符合查询条件的记录大于 一条,则返回错误。
One 方法默认返回记录的所有字段,如果需要指定返回的字段,可以在 One 方法中传入需要返回的字段名称,多个字段名称以英文逗号分隔,未指定的返回字段,返回该字段的类型零值。
示例代码:
func (u *UserController) Read() { o := orm.NewOrm() var user models.User // string 类型的表名 // err := o.QueryTable("beego_user").One(&user) // 结构体的地址 // err := o.QueryTable(&user).One(&user) // 使用对象作为表名 err := o.QueryTable(new(models.User)).One(&user) // 指定返回字段,其他字段返回字段类型的零值 // err := o.QueryTable(new(models.User)).One(&user, "Id", "Name") if err != nil { log.Fatalln(err.Error()) return } fmt.Printf("user:%+v\n", user) }
All 方法
All 方法返回对应的结果集对象,默认受 Limit 限制,最多显示 1000 条数据。All 方法的参数可以接收 []Type 和 *[]Type 两种形式的切片,如果需要指定查询的字段,可以在第二个参数开始传入字段名称,多个字段名称以英文逗号分隔,未指定查询的字段,返回字段类型的零值。
示例代码:
func (u *UserController) Read() { o := orm.NewOrm() var users []models.User rows, err := o.QueryTable("beego_user").All(&users) // 指定返回字段,其他字段返回字段类型的零值 // rows, err := o.QueryTable("beego_user").All(&users, "Id", "Name") if err != nil { log.Fatalln(err.Error()) return } fmt.Printf("rows:%d users:%+v\n", rows, users) }
Count 方法
Count 方法返回结果集行数。
示例代码:
func (u *UserController) Read() { o := orm.NewOrm() num, err := o.QueryTable(new(models.User)).Count() if err != nil { log.Fatalln(err.Error()) return } fmt.Println("num:", num) }