# 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())
```