1、数据库
(1)RegisterDriver()注册数据库类型
支持以下三种类型:
// For version 1.6
orm.DRMySQL
orm.DRSqlite
orm.DRPostgres
// < 1.6
orm.DR_MySQL
orm.DR_Sqlite
orm.DR_Postgres
// 参数1 driverName
// 参数2 数据库类型
// 这个用来设置 driverName 对应的数据库类型
// mysql / sqlite3 / postgres 这三种是默认已经注册过的,所以可以无需设置
orm.RegisterDriver("mysql", orm.DRMySQL)
(2)注册数据库
RegisterDataBase()
ORM 必须
注册一个别名
为 default
的数据库,作为默认使用。
ORM 使用 golang 自己的连接池
// 参数1 数据库的别名,用来在 ORM 中切换数据库使用
// 参数2 driverName
// 参数3 对应的链接字符串
orm.RegisterDataBase("default", "mysql", "root:root@/orm_test?charset=utf8")
// 参数4(可选) 设置最大空闲连接
// 参数5(可选) 设置最大数据库连接 (go >= 1.2)
maxIdle := 30
maxConn := 30
orm.RegisterDataBase("default", "mysql", "root:root@/orm_test?charset=utf8", maxIdle, maxConn)
(3)RegisterModel()注册模型,目的是将数据库中的表结构与模型结构体相对应。
(4)RunSyncdb()自动创建表
func init() {
// set default database
orm.RegisterDataBase("default", "mysql", "username:password@tcp(127.0.0.1:3306)/db_name?charset=utf8", 30)
// register model
orm.RegisterModel(new(User))
// create table
orm.RunSyncdb("default", false, true)
}
(5)GetDB()获取数据库对象
从已注册的数据库返回 *sql.DB 对象
,默认返回别名为 default 的数据库。
(6)Using()切换为其他数据库
orm.RegisterDataBase("db1", "mysql", "root:root@/orm_db2?charset=utf8")
orm.RegisterDataBase("db2", "sqlite3", "data.db")
o1 := orm.NewOrm()
o1.Using("db1")
o2 := orm.NewOrm()
o2.Using("db2")
// 切换为其他数据库以后
// 这个 Ormer 对象的其下的 api 调用都将使用这个数据库
(7)Driver()返回当前 ORM 使用的 db 信息
type Driver interface {
Name() string
Type() DriverType
}
orm.RegisterDataBase("db1", "mysql", "root:root@/orm_db2?charset=utf8")
orm.RegisterDataBase("db2", "sqlite3", "data.db")
o1 := orm.NewOrm()
o1.Using("db1")
dr := o1.Driver()
fmt.Println(dr.Name() == "db1") // true
fmt.Println(dr.Type() == orm.DRMySQL) // true
o2 := orm.NewOrm()
o2.Using("db2")
dr = o2.Driver()
fmt.Println(dr.Name() == "db2") // true
fmt.Println(dr.Type() == orm.DRSqlite) // true
(8)调试模式打印查询语句
简单的设置 Debug 为 true
打印查询的语句
可能存在性能问题,不建议使用在生产模式
func main() {
orm.Debug = true
...
默认使用 os.Stderr 输出日志信息
改变输出到你自己的 io.Writer
var w io.Writer
...
// 设置为你的 io.Writer
...
orm.DebugLog = orm.NewLog(w)
2、表
(1)Read()查询表
o := orm.NewOrm()
user := User{Id: 1}
err := o.Read(&user)
Read 默认
通过查询主键赋值
,可以使用指定的字段
进行查询:
user := User{Name: "slene"}
err = o.Read(&user, "Name")
(2)ReadOrCreate()尝试从数据库读取,不存在的话就创建一个
默认必须传入一个参数
作为条件字段
,同时也支持多个参数
多个条件字段
o := orm.NewOrm()
user := User{Name: "slene"}
// 三个返回参数依次为:是否新创建的,对象 Id 值,错误
if created, id, err := o.ReadOrCreate(&user, "Name"); err == nil {
if created {
fmt.Println("New Insert an object. Id:", id)
} else {
fmt.Println("Get an object. Id:", id)
}
}
(3)Insert()第一个返回值为自增健 Id 的值
o := orm.NewOrm()
var user User
user.Name = "slene"
user.IsActive = true
id, err := o.Insert(&user)
if err == nil {
fmt.Println(id)
}
创建后会自动对 auto 的 field 赋值
(4)InsertMulti()
同时插入多个对象
类似sql语句
insert into table (name, age) values("slene", 28),("astaxie", 30),("unknown", 20)
第一个参数 bulk 为并列插入的数量,第二个为对象的slice
返回值为成功插入的数量
users := []User{
{Name: "slene"},
{Name: "astaxie"},
{Name: "unknown"},
...
}
successNums, err := o.InsertMulti(100, users)
bulk 为 1 时,将会顺序插入 slice 中的数据
(5)Update()第一个返回值为影响的行数
o := orm.NewOrm()
user := User{Id: 1}
if o.Read(&user) == nil {
user.Name = "MyName"
if num, err := o.Update(&user); err == nil {
fmt.Println(num)
}
}
Update 默认更新所有的字段
,可以更新指定的字段
:
// 只更新 Name
o.Update(&user, "Name")
// 指定多个字段
// o.Update(&user, "Field1", "Field2", ...)
...
(6)Delete()
第一个返回值为影响的行数
o := orm.NewOrm()
if num, err := o.Delete(&User{Id: 1}); err == nil {
fmt.Println(num)
}
3、高级查询
(1)获取查询需要的QuerySeter 对象
o := orm.NewOrm()
// 获取 QuerySeter 对象,user 为表名(或表结构)
qs := o.QueryTable("user")
(2)Filter()用来过滤查询
结果,起到 包含条件
的作用
多个 Filter
之间使用 AND
连接
(3)Exclude()用来过滤查询
结果,起到 排除条件
的作用
使用 NOT
排除条件
多个 Exclude
之间使用 AND
连接
(4)SetCond()自定义条件表达式
cond := orm.NewCondition()
cond1 := cond.And("profile__isnull", false).AndNot("status__in", 1).Or("profile__age__gt", 2000)
qs := orm.QueryTable("user")
qs = qs.SetCond(cond1)
// WHERE ... AND ... AND NOT ... OR ...
cond2 := cond.AndCond(cond1).OrCond(cond.And("name", "slene"))
qs = qs.SetCond(cond2).Count()
// WHERE (... AND ... AND NOT ... OR ...) OR ( ... )
(5)Limit()限制最大返回数据行数,第二个参数可以设置 Offset
var DefaultRowsLimit = 1000 // ORM 默认的 limit 值为 1000
// 默认情况下 select 查询的最大行数为 1000
// LIMIT 1000
qs.Limit(10)
// LIMIT 10
qs.Limit(10, 20)
// LIMIT 10 OFFSET 20 注意跟 SQL 反过来的
qs.Limit(-1)
// no limit
qs.Limit(-1, 100)
// LIMIT 18446744073709551615 OFFSET 100
// 18446744073709551615 是 1<<64 - 1 用来指定无 limit 限制 但有 offset 偏移的情况
(6)Offset()设置 偏移行数
qs.Offset(20)
// LIMIT 1000 OFFSET 20
(7)GroupBy()
qs.GroupBy("id", "age")
// GROUP BY id,age
(8)OrderBy()
参数使用 expr
在 expr 前
使用减号 -
表示 DESC
的排列
qs.OrderBy("id", "-profile__age")
// ORDER BY id ASC, profile.age DESC
qs.OrderBy("-profile__age", "profile")
// ORDER BY profile.age DESC, profile_id ASC
(9)Distinct()对应 sql 的 distinct
语句, 返回不重复的值.
qs.Distinct()
// SELECT DISTINCT
(10)Count()依据当前的查询条件,返回结果行数
cnt, err := o.QueryTable("user").Count() // SELECT COUNT(*) FROM USER
fmt.Printf("Count Num: %s, %s", cnt, err)
(11)Exist()判断查询条件存在
exist := o.QueryTable("user").Filter("UserName", "Name").Exist()
fmt.Printf("Is Exist: %s", exist)
(12)Update()依据当前查询条件
,进行批量更新
操作
num, err := o.QueryTable("user").Filter("name", "slene").Update(orm.Params{
"name": "astaxie",
})
fmt.Printf("Affected Num: %s, %s", num, err)
// SET name = "astaixe" WHERE name = "slene"
原子操作增加字段值
// 假设 user struct 里有一个 nums int 字段
num, err := o.QueryTable("user").Update(orm.Params{
"nums": orm.ColValue(orm.ColAdd, 100),
})
// SET nums = nums + 100
orm.ColValue
支持以下操作
ColAdd // 加
ColMinus // 减
ColMultiply // 乘
ColExcept // 除
(13)Delete()依据当前查询条件
,进行批量删除操作
num, err := o.QueryTable("user").Filter("name", "slene").Delete()
fmt.Printf("Affected Num: %s, %s", num, err)
// DELETE FROM user WHERE name = "slene"
(14)All()
返回对应的结果集对象
All 的参数支持 *[]Type 和 *[]*Type 两种形式的 slice
var users []*User
num, err := o.QueryTable("user").Filter("name", "slene").All(&users)
fmt.Printf("Returned Rows Num: %s, %s", num, err)
All / Values / ValuesList / ValuesFlat 受到 Limit 的限制,默认最大行数为 1000
(15)One()尝试返回单条记录
var user User
err := o.QueryTable("user").Filter("name", "slene").One(&user)
if err == orm.ErrMultiRows {
// 多条的时候报错
fmt.Printf("Returned Multi Rows Not One")
}
if err == orm.ErrNoRows {
// 没有找到记录
fmt.Printf("Not row found")
}
(16)Values()获取的查询的值,是多个键值对
返回结果集的 key => value 值
key 为Model里的Field name
, value的值是interface{}类型
,例如,如果你要将value赋值给struct中的某字段
,需要根据结构体对应字段类型使用断言
获取真实值
。举例:Name : m[“Name”].(string)
var maps []orm.Params
num, err := o.QueryTable("user").Values(&maps)
if err == nil {
fmt.Printf("Result Nums: %d\n", num)
for _, m := range maps {
fmt.Println(m["Id"], m["Name"])
}
}
eg、
if _, err := db.Raw(templateSql, extractorIds).Values(&templateMaps); err != nil {}
4、使用原生的sql
ids := []int{1, 2, 3}
p.Raw("SELECT name FROM user WHERE id IN (?, ?, ?)", ids)
创建一个 RawSeter
o := orm.NewOrm()
var r RawSeter
r = o.Raw("UPDATE user SET name = ? WHERE name = ?", "testing", "slene")
(1)QueryRow()返回一条查询语句
type User struct {
Id int
UserName string
}
var user User
err := o.Raw("SELECT id, user_name FROM user WHERE id = ?", 1).QueryRow(&user)
(2)QueryRows()返回多条查询语句
QueryRows 支持的对象还有 map 规则是和 QueryRow 一样的,但都是 slice
type User struct {
Id int
UserName string
}
var users []User
num, err := o.Raw("SELECT id, user_name FROM user WHERE id = ?", 1).QueryRows(&users)
if err == nil {
fmt.Println("user nums: ", num)
}
(3)Values / ValuesList / ValuesFlat返回结果集
Values()返回任何类型
返回结果集的 key => value
值
var maps []orm.Params
num, err := o.Raw("SELECT user_name FROM user WHERE status = ?", 1).Values(&maps)
if err == nil && num > 0 {
fmt.Println(maps[0]["user_name"]) // slene
}
ValuesList()返回结果集 slice
var lists []orm.ParamsList
num, err := o.Raw("SELECT user_name FROM user WHERE status = ?", 1).ValuesList(&lists)
if err == nil && num > 0 {
fmt.Println(lists[0][0]) // slene
}
ValuesFlat()返回单一字段的平铺 slice 数据
var list orm.ParamsList
num, err := o.Raw("SELECT id FROM user WHERE id < ?", 10).ValuesFlat(&list)
if err == nil && num > 0 {
fmt.Println(list) // []{"1","2","3",...}
}