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