Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

数据查询

Where/And/Or查询条件

这三个方法用于传递查询条件参数,支持的参数为任意的string/map/slice/struct/*struct类型。

...

type Condition struct{
    Sex int `orm:"sex"`
    Age int `orm:"age"`
}
Where(Condition{1, 18})
// WHERE `sex`=1 AND `age`=18

WherePri支持主键的查询条件

WherePri方法的功能同Where,但提供了对表主键的智能识别,常用于根据主键的便捷数据查询。假如user表的主键为uid,我们来看一下WhereWherePri的区别:

...

可以看到,当使用WherePri方法且给定参数为单一的参数基本类型或者slice类型时,将会被识别为主键的查询条件值。

All/One/Array/Value/Count数据查询

这四个方法是数据查询比较常用的方法: 1. All 用于查询并返回多条记录的列表/数组。 1. One 用于查询并返回单条记录。 1. Array 用于查询指定字段列的数据,返回数组。 1. Value 用于查询并返回一个字段值,往往需要结合Fields方法使用。 1. Count 用于查询并返回记录数。

...

// SELECT `name` FROM `user` WHERE `score`>60
Table("user").Array("name", "score>?", 60)

// SELECT `name` FROM `user` WHERE `uid`=1
Table("user").Value("name", "uid=1")
Table("user").Value("name", "uid", 1)
// SELECT `name` FROM `user` WHERE `uid` IN(1,2,3)
Table("user").Value("name", "uid", g.Slice{1,2,3})

Struct/Structs/Scan数据查询

这三个方法用于便捷地将查询的结果转换为struct/*struct或者[]struct/[]*struct数据。 1. Struct: 将查询结果转换为一个struct对象,查询结果应当是特定的一条记录,并且pointer参数应当为struct对象的指针地址(*struct或者**struct),使用方式例如: go type User struct { Id int Passport string Password string NickName string CreateTime gtime.Time } user := new(User) err := db.Table("user").Where("id", 1).Struct(user) 或者 go user := &User{} err := db.Table("user").Where("id", 1).Struct(user) 前两种方式都是预先初始化对象(提前分配内存),推荐的方式: go user := (*User)(nil) err := db.Table("user").Where("id", 1).Struct(&user) 这种方式只有在查询到数据的时候才会执行初始化及内存分配。注意在用法上的区别,特别是传递参数类型的差别(前两种方式传递的参数类型是*User,这里传递的参数类型其实是**User)。 1. Structs: 将多条查询结果集转换为一个[]struct/[]*struct数组,查询结果应当是多条记录组成的结果集,并且pointer应当为数组的指针地址,使用方式例如: go users := ([]User)(nil) // 或者 var users []User err := db.Table("user").Structs(&users) 或者 go users := ([]*User)(nil) // 或者 var user []*User err := db.Table("user").Structs(&users) 1. Scan: 该方法会根据输入参数pointer的类型选择调用Struct还是Structs方法。如果结果是特定的一条记录,那么调用Struct方法;如果结果是slice类型则调用Structs方法。

Find*支持主键条件的数据查询

Find*方法包含:FindAll/FindOne/FineValue/FindCount/FindScan,这些方法与All/One/Value/Count/Scan方法的区别在于,当方法直接给定条件参数时,前者的效果与WherePri方法一致;而后者的效果与Where方法一致。也就是说Find*方法的条件参数支持智能主键识别特性。

LeftJoin/RightJoin/InnerJoin关联查询

  1. LeftJoin 左关联查询;
  2. RightJoin 右关联查询;
  3. InnerJoin 内关联查询;

...

// 查询符合条件的单条记录(第一条)
// SELECT u.*,ud.site FROM user u LEFT JOIN user_detail ud ON u.uid=ud.uid WHERE u.uid=1 LIMIT 1
r, err := db.Table("user u").LeftJoin("user_detail ud", "u.uid=ud.uid").Fields("u.*,ud.site").Where("u.uid", 1).One()

// 查询指定字段值
// SELECT ud.site FROM user u RIGHT JOIN user_detail ud ON u.uid=ud.uid WHERE u.uid=1 LIMIT 1
r, err := db.Table("user u").RightJoin("user_detail ud", "u.uid=ud.uid").Fields("ud.site").Where("u.uid", 1).Value()

// 分组及排序
// SELECT u.*,ud.city FROM user u INNER JOIN user_detail ud ON u.uid=ud.uid GROUP BY city ORDER BY register_time asc
r, err := db.Table("user u").InnerJoin("user_detail ud", "u.uid=ud.uid").Fields("u.*,ud.city").Group("city").Order("register_time asc").All()

// 不使用join的联表查询
// SELECT u.*,ud.city FROM user u,user_detail ud WHERE u.uid=ud.uid
r, err := db.Table("user u,user_detail ud").Where("u.uid=ud.uid").Fields("u.*,ud.city").All()

Group/Order分组与排序

Group方法用于查询分组,Order方法用于查询排序。使用示例:

// SELECT COUNT(*) total,age FROM `user` GROUP BY age
r, err := db.Table("user").Fields("COUNT(*) total,age").Group("age").All()

// SELECT * FROM `student` ORDER BY class asc,course asc,score desc
r, err := db.Table("student").Order("class asc,course asc,score desc").All()

Having条件过滤

Having方法用于查询结果的条件过滤。使用示例:

// SELECT COUNT(*) total,age FROM `user` GROUP BY age HAVING total>100
r, err := db.Table("user").Fields("COUNT(*) total,age").Group("age").Having("total>100").All()

// SELECT * FROM `student` ORDER BY class HAVING score>60
r, err := db.Table("student").Order("class").Having("score>?", 60).All()

自定义数据表别名

// SELECT * FROM `user` AS u LEFT JOIN `user_detail` as ud ON(ud.id=u.id) WHERE u.id=1 LIMIT 1
r, err := db.Table("user", "u").LeftJoin("user_detail", "ud", "ud.id=u.id").Where("u.id", 1).One()
r, err := db.Table("user").As("u").LeftJoin("user_detail", "ud", "ud.id=u.id").Where("u.id", 1).One()

示例1, 基本使用

Where + string,条件参数使用字符串和预处理。

...

condition := g.Map{
    "title like ?"         : "%九寨%",
    "online"               : 1,
    "hits between ? and ?" : g.Slice{1, 10},
    "exp > 0"              : nil,
    "category"             : g.Slice{100, 200},
}
result, err := db.Table("article").Where(condition).All()
// SELECT * FROM article WHERE title like '%九寨%' AND online=1 AND hits between 1 and 10 AND exp > 0 AND category IN(100,200)

示例2, select in查询

使用字符串、slice参数类型。当使用slice参数类型时,预处理占位符只需要一个?即可。

...

type User struct {
    Id     []int  `orm:"uid"`
    Gender int    `orm:"gender"`
}
// SELECT * FROM `user` WHERE uid IN(100,10000,90000) AND gender=1
r, err := db.Table("user").Where(User{
    "gender" : 1,
    "uid"    : []int{100, 10000, 90000},
}).All()

示例3, like查询

// SELECT * FROM `user` WHERE name like '%john%'
r, err := db.Table("user").Where("name like ?", "%john%").All()
// SELECT * FROM `user` WHERE birthday like '1990-%'
r, err := db.Table("user").Where("birthday like ?", "1990-%").All()

示例4, sum查询

// SELECT SUM(score) FROM `user` WHERE `uid`=1
r, err := db.Table("user").Fields("SUM(score)").Where("uid", 1).Value()

示例5, count查询

// SELECT COUNT(1) FROM `user` WHERE `birthday`='1990-10-01'
r, err := db.Table("user").Where("birthday", "1990-10-01").Count()
// SELECT COUNT(uid) FROM `user` WHERE `birthday`='1990-10-01'
r, err := db.Table("user").Fields("uid").Where("birthday", "1990-10-01").Count()

示例6, distinct查询

// SELECT DISTINCT uid,name FROM `user `
r, err := db.Table("user").Fields("DISTINCT uid,name").All()
// SELECT COUNT(DISTINCT uid,name) FROM `user `
r, err := db.Table("user").Fields("DISTINCT uid,name").Count()

示例7, between查询

// SELECT * FROM `user ` WHERE age between 18 and 20
r, err := db.Table("user").Where("age between ? and ?", 18, 20).All()