使用SQL语句进行查询
在实际生产中,各种业务逻辑,model不能很好的满足需求,所以就可以使用原生的sql。当然,如果你对sql比较熟悉,你会发现orm有时候没有原生sql来的灵活,下面介绍beego的原生sql。
使用 Raw SQL 查询,无需使用 ORM 表定义
多数据库,都可直接使用占位符号
?
,自动转换,可以防止sql注入查询时的参数,支持使用 Model Struct 和 Slice, Array
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")
我们来看看源代码接口定义:
type RawSeter interface { //execute sql and get result Exec() (sql.Result, error) //query data and map to container //for example: // var name string // var id int // rs.QueryRow(&id,&name) // id==2 name=="slene" QueryRow(containers ...interface{}) error // query data rows and map to container // var ids []int // var names []int // query = fmt.Sprintf("SELECT 'id','name' FROM %suser%s", Q, Q) // num, err = dORM.Raw(query).QueryRows(&ids,&names) // ids=>{1,2},names=>{"nobody","slene"} QueryRows(containers ...interface{}) (int64, error) SetArgs(...interface{}) RawSeter // query data to []map[string]interface // see QuerySeter's Values Values(container *[]Params, cols ...string) (int64, error) // query data to [][]interface // see QuerySeter's ValuesList ValuesList(container *[]ParamsList, cols ...string) (int64, error) // query data to []interface // see QuerySeter's ValuesFlat ValuesFlat(container *ParamsList, cols ...string) (int64, error) // query all rows into map[string]interface with specify key and value column name. // keyCol = "name", valueCol = "value" // table data // name | value // total | 100 // found | 200 // to map[string]interface{}{ // "total": 100, // "found": 200, // } RowsToMap(result *Params, keyCol, valueCol string) (int64, error) // query all rows into struct with specify key and value column name. // keyCol = "name", valueCol = "value" // table data // name | value // total | 100 // found | 200 // to struct { // Total int // Found int // } RowsToStruct(ptrStruct interface{}, keyCol, valueCol string) (int64, error) // return prepared raw statement for used in times. // for example: // pre, err := dORM.Raw("INSERT INTO tag (name) VALUES (?)").Prepare() // r, err := pre.Exec("name1") // INSERT INTO tag (name) VALUES (`name1`) Prepare() (RawPreparer, error) }
下面具体介绍一下接口:
Exec
执行 sql 语句,返回 sql.Result 对象
res, err := o.Raw("UPDATE user SET name = ?", "your").Exec()if err == nil { num, _ := res.RowsAffected() fmt.Println("mysql row affected nums: ", num) }
QueryRow
QueryRow 和 QueryRows 提供高级 sql mapper 功能
支持 struct
type User struct { Id int UserName string} var user User err := o.Raw("SELECT id, user_name FROM user WHERE id = ?", 1).QueryRow(&user)
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) }
SetArgs
改变 Raw(sql, args…) 中的 args 参数,返回一个新的 RawSeter
用于单条 sql 语句,重复利用,替换参数然后执行。
res, err := r.SetArgs("arg1", "arg2").Exec() res, err := r.SetArgs("arg1", "arg2").Exec() ...
Values / ValuesList / ValuesFlat
Raw SQL 查询获得的结果集 Value 为 string
类型,NULL 字段的值为空 ``
from beego 1.1.0
Values, ValuesList, ValuesFlat 的参数,可以指定返回哪些 Columns 的数据
通常情况下,是无需指定的,因为 sql 语句中你可以自行设置 SELECT 的字段
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",...}}
RowsToMap
SQL 查询结果是这样
name | value |
---|---|
total | 100 |
found | 200 |
查询结果匹配到 map 里
res := make(orm.Params) nums, err := o.Raw("SELECT name, value FROM options_table").RowsToMap(&res, "name", "value")// res is a map[string]interface{}{// "total": 100,// "found": 200,// }
RowsToStruct
SQL 查询结果是这样
name | value |
---|---|
total | 100 |
found | 200 |
查询结果匹配到 struct 里
type Options struct { Total int Found int} res := new(Options) nums, err := o.Raw("SELECT name, value FROM options_table").RowsToStruct(res, "name", "value") fmt.Println(res.Total) // 100fmt.Println(res.Found) // 200
匹配支持的名称转换为 snake -> camel, eg: SELECT user_name … 需要你的 struct 中定义有 UserName
Prepare
用于一次 prepare 多次 exec,以提高批量执行的速度。
p, err := o.Raw("UPDATE user SET name = ? WHERE name = ?").Prepare() res, err := p.Exec("testing", "slene") res, err = p.Exec("testing", "astaxie") ... ... p.Close() // 别忘记关闭 statement
构造查询
QueryBuilder 提供了一个简便,流畅的 SQL 查询构造器。在不影响代码可读性的前提下用来快速的建立 SQL 语句。
QueryBuilder 在功能上与 ORM 重合, 但是各有利弊。ORM 更适用于简单的 CRUD 操作,而 QueryBuilder 则更适用于复杂的查询,例如查询中包含子查询和多重联结。
使用方法:
// User 包装了下面的查询结果type User struct { Name string Age int} var users []User// 获取 QueryBuilder 对象. 需要指定数据库驱动参数。// 第二个返回值是错误对象,在这里略过qb, _ := orm.NewQueryBuilder("mysql")// 构建查询对象qb.Select("user.name", "profile.age"). From("user"). InnerJoin("profile").On("user.id_user = profile.fk_user"). Where("age > ?"). OrderBy("name").Desc(). Limit(10).Offset(0)// 导出 SQL 语句sql := qb.String()// 执行 SQL 语句o := orm.NewOrm() o.Raw(sql, 20).QueryRows(&users)
完整 API 接口:
// QueryBuilder is the Query builder interfacetype QueryBuilder interface { Select(fields ...string) QueryBuilder ForUpdate() QueryBuilder From(tables ...string) QueryBuilder InnerJoin(table string) QueryBuilder LeftJoin(table string) QueryBuilder RightJoin(table string) QueryBuilder On(cond string) QueryBuilder Where(cond string) QueryBuilder And(cond string) QueryBuilder Or(cond string) QueryBuilder In(vals ...string) QueryBuilder OrderBy(fields ...string) QueryBuilder Asc() QueryBuilder Desc() QueryBuilder Limit(limit int) QueryBuilder Offset(offset int) QueryBuilder GroupBy(fields ...string) QueryBuilder Having(cond string) QueryBuilder Update(tables ...string) QueryBuilder Set(kv ...string) QueryBuilder Delete(tables ...string) QueryBuilder InsertInto(table string, fields ...string) QueryBuilder Values(vals ...string) QueryBuilder Subquery(sub string, alias string) string String() string}
作者:若与
链接:https://www.jianshu.com/p/1fddea2550c1
共同学习,写下你的评论
评论加载中...
作者其他优质文章