go语言web开发20 - beego框架之go orm使用05 - orm使用原生sql
一、orm原生sql之Exec方法
Exec方法只能执行 “插入、删除、更新数据” 的sql操作,不能执行查询操作,具体看下面示例:
1.1、原生sql插入数据操作
ret, err := o.Raw(`INSERT into article(title, author, read_count) VALUE(?, ?, ?)`, "beego详解", "优选出品", 99999).Exec() if err != nil { fmt.Println("insert data failed, err:", err) } fmt.Println(ret.LastInsertId()) // 插入数据的id fmt.Println(ret.RowsAffected()) // 受影响的行数
1.2、原生sql执行更新操作
ret, err := o.Raw(`UPDATE article set title=? WHERE id = ?`, "beego详解", 14).Exec() if err != nil { fmt.Println("update data failed, err:", err) } fmt.Println(ret.LastInsertId()) // 更新数据的id fmt.Println(ret.RowsAffected()) // 受影响的行数
1.3、原生sql执行删除操作
r := o.Raw(`DELETE FROM article WHERE id=?`, 15) ret, err := r.Exec() // Exec:可以执行修改数据库的一些操作(增删改),不能用于查询,执行sql语句,返回sql.Result对象 if err != nil { fmt.Println("Row failed, err:", err) } fmt.Println(ret.LastInsertId()) // 删除行的id fmt.Println(ret.RowsAffected()) // 受影响的行数
二、orm原生sql之QueryRow与QueryRows方法
- QueryRow:查询一条数据
- QueryRows:查询多条数据
2.1、QueryRow:查询单挑数据
ret_article := models.Article{} err := o.Raw(`SELECT id, title, author, read_count from article WHERE id = ?`, 13).QueryRow(&ret_article) // QueryRow:查询一条数据 if err != nil { fmt.Println("QueryRow failed, err:", err) } fmt.Println(ret_article)
2.2、QueryRows:查询多条数据
ret_articles := []test_orm.Article{} err := o.Raw(`SELECT id, title, author, read_count from article WHERE title = ?`, "beego详解").QueryRows(&ret_articles) // QueryRows:查询多条数据 if err != nil { fmt.Println("QueryRows failed, err:", err) } fmt.Println(ret_articles)
三、SetArgs方法使用
在执行原生sql的使用通过用 ? 号占位,然后通过传参拼接的形式组成完整的sql,这里提供了SetArgs方法来设置参数,具体使用方法看下面例子
ret_articles := []test_orm.Article{} num, err := o.Raw(`SELECT id, title, author, read_count from article WHERE title = ?`).SetArgs("优选工具").QueryRows(&ret_articles) if err != nil { fmt.Println("SetArgs failed, err:", err) } fmt.Printf("受影响%d行\n", num) fmt.Println(ret_articles)
3.1、SetArgs之封装函数
我们可以将SetArgs封装到一个函数里,调用的时候直接传参即可,具体看下面例子
(1)、SetArgs封装
func QueryArticleRowsByFieldAndValue(field_name, field_value string) []test_orm.Article { o := orm.NewOrm() o.Using("default") articles := []test_orm.Article{} r := o.Raw("SELECT id, title, author, read_count from article WHERE "+field_name+" = ?") r.SetArgs(field_value).QueryRows(&articles) return articles }
(2)、调用封装后的函数
ret_articles1 := utils.QueryArticleRowsByFieldAndValue("title","beego详解") ret_articles2 := utils.QueryArticleRowsByFieldAndValue("author","go语言从入门到放弃") fmt.Println(ret_articles1) fmt.Println(ret_articles2)
四、Values、ValuesList、ValuesFlat
这里的Values、ValuesList、ValuesFlat和orm操作数据库里的Values、ValuesList、ValuesFlat性质是一样的。
4.1、Values:将查询的结果放到切片里,切片里是map类型
var params []orm.Params r := o.Raw(`SELECT id, title, author, read_count from article WHERE title = ?`, "beego详解") r.Values(¶ms) fmt.Println(params)
4.2、ValuesList:将结果放到切片里,切片里是数组
var valueList []orm.ParamsList r := o.Raw(`SELECT id, title, author, read_count from article WHERE title = ?`, "优选工具") r.ValuesList(&valueList) fmt.Println(valueList)
4.3、ValuesFlat:值查询某个字段,将查询的字段放到数组里
var params orm.ParamsList r := o.Raw(`SELECT title from article WHERE title = ?`, "优选工具") r.ValuesFlat(¶ms) fmt.Println(params)
五、RowsToStruct、RowsToMap、Prepare
- RowsToStruct:将数据库里指定的某个字段的值转换为结构体字段的key,数据库里某个字段的值转换为结构体字段key对应的value
- RowsToMap:将数据库里指定的某个字段的值转换为map字段的key,数据库里某个字段的值转换为map字段key对应的value
- Prepare:一次准备多次执行
5.1、RowsToStruct
使用场景:数据统计
// 1、定义结构体并定义一个自定义结构体类型的变量 type ToStruct struct { Total string Page string } var to_struct = ToStruct{} // 2、 查询数据,并将数据赋值到结构体变量里 t := o.Raw(`SELECT name, value FROM to_struct`) t.RowsToStruct(&to_struct, "name", "value") // 将数据库里name字段的值作为结构体的key,value字段的值作为key对应的value存储到结构体里 fmt.Println(to_struct.Total) fmt.Println(to_struct.Page)
5.1、RowsToMap
to_map := make(orm.Params) t := o.Raw(`SELECT name, value FROM to_struct`) t.RowsToMap(&to_map,"name", "value") // 将数据库里name字段的值作为map的key,value字段的值作为key对应的value存储到map里 fmt.Println(to_map["total"]) fmt.Println(to_map["page"])
5.3、Prepare
t := o.Raw(`INSERT INTO article(title, author, read_count) value(?, ?, ?)`) rp, _ := t.Prepare() // 两个返回值,RunPrepare和错误信息 rp.Exec("beego详解1", "zs1", 99991) // 连续插入多次 rp.Exec("beego详解2", "zs2", 99992) rp.Exec("beego详解3", "zs3", 99993) rp.Exec("beego详解4", "zs4", 99994) rp.Close() // Prepare用完了一定要关了