# 4.3 api示例 ## `Table()`上一张已经做了详细说明 ## `Fields()`和`AddFields()` ```go db.Table("users").Fields("uid").AddFields("name,age").First() ``` > Fields()会替换为最新的字段, AddFields()则会追加最新字段, 只有当传入得table为string和map类型时有效,传入struct时该方法无效,因为会自动解析struct自身的字段 ## `Distinct()` ```go db.Table("users").Distinct().First() ``` ## `Where`,`OrWhere`,`WhereNull / WhereNotNull`,`WhereIn / WhereNotIn / OrWhereIn / OrWhereNotIn`,`WhereBetween / WhereBetwee / OrWhereBetween / OrWhereNotBetween` ```go // select * from users where id=1 db.Table(&user).Where("id", 1).Select() // select * from users where id>1 db.Table(&user).Where("id", ">", 1).Select() // select * from users where id>1 and name like "%fizz%" db.Table(&user).Where("id", ">", 1).Where("name","like","%fizz%").Select() // select * from users where id>1 or name like "%fizz%" db.Table(&user).Where("id", ">", 1).OrWhere("name","like","%fizz%").Select() // select * from users where job is null db.Table(&users).WhereNull("job").Select() // select * from users where job is not null db.Table(&users).WhereNotNull("job").Select() // select * from users where age in (17,18) db.Table(&users).WhereIn("age",[]interface{}{17, 18}).Select() // select * from users where age between 17 and 20 db.Table(&users).WhereBetween("age",[]interface{}{17, 18}).Select() // select * from users where uid=1 and age=18 limit 1 db.Table("users").Where(gorose.Data{"uid":1, "age":18}).First() ``` ## 嵌套where ```go // SELECT * FROM users // WHERE uid > 1 // and ( name = 'fizz' // or ( name = 'fizz2' // and ( name = 'fizz3' or website like 'fizzday%') // ) // ) // and job = 'it' LIMIT 1 User := db.Table("users") User.Where("uid", ">", 1).Where(func() { User.Where("name", "fizz").OrWhere(func() { User.Where("name", "fizz2").Where(func() { User.Where("name", "fizz3").OrWhere("website", "like", "fizzday%") }) }) }).Where("job", "it").First() ``` ## Join / LeftJoin / RightJoin / CrossJoin / UnionJoin ```go // 普通示例 // select * from user inner join card on user.id=card.user_id limit 10 db.Table("user") .Join("card","user.id","=","card.user_id") .Limit(10) .Get() // 左链接 // select * from user a left join card b on a.id=b.user_id limit 1 db.Table("user a") .LeftJoin("card b on a.id = b.user_id") .First() // RightJoin => right join // CrossJoin => cross join // UnionJoin => union join ``` 默认 `join` 是 `inner join` ## Order / OrderBy ```go // select * from users order by id desc, job asc db.Table(&user).Order("id desc, job asc").Select() ``` Order 等同于 orderby ## Group / GroupBy ```go // select * from users group by job db.Table(&user).Group("job").Select() ``` Group 等同于 GroupBy ## Limit 和 Offset ```go // select * from users limit 10 offset 10 db.Table(&user).Limit(10).Offset(10).Select() ``` ## Having ```go // select * from users group by job having age>17 db.Table(&user).Group("job").Having("age>17").Select() ``` ## Value 获取一个字段的单一值 ```go // 获取id=1的job db.Table(&user).Value("job") // it ``` ## Pluck 获取表的一列值 ```go // 获取id=1的job db.Table(&user).Pluck("job") // ["id", "drawer"] // 可以指定第二个参数, 第二个参数的值, 做为第一个字段值得key, 这两个参数都必须为表的字段 db.Table(&user).Pluck("job", "name") // {"fizz":id", "fizz2":"drawer"} ``` ## Sum / Count / Avg / Max / Min 聚合查询 ```go // select sum(age) from users db.Table(&user).Sum("age") db.Table(&user).Count() db.Table(&user).Count("*") db.Table(&user).Avg("age") db.Table(&user).Max("age") db.Table(&user).Min("age") ``` ## Chunk 数据分片 大量数据批量处理 (累积处理) ```go ` 当需要操作大量数据的时候, 一次性取出再操作, 不太合理, 就可以使用chunk方法 chunk的第一个参数是指定一次操作的数据量, 根据业务量, 取100条或者1000条都可以 chunk的第二个参数是一个回调方法, 用于书写正常的数据处理逻辑 目的是做到, 无感知处理大量数据 实现原理是, 每一次操作, 自动记录当前的操作位置, 下一次重复取数据的时候, 从当前位置开始取 ` User := db.Table("users") User.Fields("id, name").Where("id",">",2).Chunk(2, func(data []gorose.Data) error { // for _,item := range data { // fmt.Println(item) // } fmt.Println(data) // 这里不要忘记返回错误或nil return nil }) // 打印结果: // map[id:3 name:gorose] // map[id:4 name:fizzday] // map[id:5 name:fizz3] // map[id:6 name:gohouse] [map[id:3 name:gorose] map[name:fizzday id:4]] [map[id:5 name:fizz3] map[id:6 name:gohouse]] ``` ##Loop 数据分片 大量数据批量处理 (从头处理) ```go ` 类似 chunk 方法, 实现原理是, 每一次操作, 都是从头开始取数据 原因: 当我们更改数据时, 更改的结果可能作为where条件会影响我们取数据的结果,所以, 可以使用Loop` User := db.Table("users") User.Fields("id, name").Where("id",">",2).Loop(2, func(data []gorose.Data) error { // for _,item := range data { // fmt.Println(item) // } // 这里执行update / delete 等操作 // 这里不要忘记返回错误或nil return nil }) ``` ## 获取sql记录 - 直接构建sql而不执行 ```go // select 语句 db.Table().BuildSql() // 或者 xxx.BuildSql("select") // insert db.Table().Data().BuildSql("insert") // update, delete // xxx.BuildSql("update") // xxx.BuildSql("delete") ``` - 执行过程中获取sql ```go // 要先新建会话 db := DB() db.Table().xxx() // 获取最后一条sql fmt.Println(db.LastSql()) ```