在业务系统开发中,尤其是后台管理系统,列表页展示的数据来自多个数据源,列表页需要支持分页,怎么解决?
如上图,数据源可能来自不同 DB 数据库,可能来自不同 API 接口,也可能来自 DB 和 API 的组合。
我这也没有太好的解决方案,接到这样的需求,肯定首先和需求方沟通,这样分页是否合理。
无非就两种方案:
如果以某一数据源进行分页,其他字段去其他数据源获取,这样还好处理一些。
如果以多个数据源融合后再分页的话,就数据定期同步 或 内存中分页吧。
数据定期同步方案可以根据实际情况去设计同步频率,至于同步到 ES/MySQL/MongoDB 自己决定即可。
关于内存中分页方案,下面分享两个小方法,供参考。
$data = [ 0 => ['name' => "姓名1", 'age' => "年龄1"], 1 => ['name' => "姓名2", 'age' => "年龄2"], 2 => ['name' => "姓名3", 'age' => "年龄3"], 3 => ['name' => "姓名4", 'age' => "年龄4"], 4 => ['name' => "姓名5", 'age' => "年龄5"], 5 => ['name' => "姓名6", 'age' => "年龄6"], 6 => ['name' => "姓名7", 'age' => "年龄7"], 7 => ['name' => "姓名8", 'age' => "年龄8"], 8 => ['name' => "姓名9", 'age' => "年龄9"], 9 => ['name' => "姓名10", 'age' => "年龄10"], ]; /** * 数组分页 * @param array $arrayData 数组数据 * @param int $page 第几页 * @param int $pageSize 每页展示条数 * @return array */ function arrayToPageData($arrayData = [], $page = 1, $pageSize = 10) { $arrayData = array_values((array)$arrayData); $pageData['list'] = array_slice($arrayData, ($page - 1) * $pageSize, $pageSize); $pageData['pagination']['total'] = count($arrayData); $pageData['pagination']['currentPage'] = $page; $pageData['pagination']['prePageCount'] = $pageSize; return $pageData; } echo json_encode(arrayToPageData($data, 2, 3));
输出:
{ "list": [ { "name": "姓名4", "age": "年龄4" }, { "name": "姓名5", "age": "年龄5" }, { "name": "姓名6", "age": "年龄6" } ], "pagination": { "total": 10, "currentPage": 2, "prePageCount": 3 } }
package main import ( "encoding/json" "fmt" ) type User []struct { Name string `json:"name"` Age string `json:"age"` } type Pagination struct { Total int `json:"total"` CurrentPage int `json:"currentPage"` PrePageCount int `json:"prePageCount"` } type ListPageData struct { List User `json:"list"` Pagination Pagination `json:"pagination"` } func main() { jsonStr := `[{"name": "姓名1","age": "年龄1"}, {"name": "姓名2","age": "年龄2"}, {"name": "姓名3","age": "年龄3"}, {"name": "姓名4","age": "年龄4"}, {"name": "姓名5","age": "年龄5"}, {"name": "姓名6","age": "年龄6"}, {"name": "姓名7","age": "年龄7"}, {"name": "姓名8","age": "年龄8"}, {"name": "姓名9","age": "年龄9"}, {"name": "姓名10","age": "年龄10"} ]` var user User err := json.Unmarshal([]byte(jsonStr), &user) if err != nil { fmt.Println(err.Error()) } page := 2 pageSize := 3 pageData := ArraySlice(user, page, pageSize) listPageData := ListPageData{} listPageData.List = pageData listPageData.Pagination.Total = len(user) listPageData.Pagination.CurrentPage = page listPageData.Pagination.PrePageCount = pageSize jsonData, _ := JsonEncode(listPageData) fmt.Println(jsonData) } func JsonEncode(v interface{}) (string, error) { bytes, err := json.Marshal(v) if err != nil { return "", err } return string(bytes), nil } func ArraySlice(u User, page int, pageSize int) User { offset := (page - 1) * pageSize if offset > int(len(u)) { panic("offset: the offset is less than the length of u") } end := offset + pageSize if end < int(len(u)) { return u[offset:end] } return u[offset:] }
输出:
{ "list": [ { "name": "姓名4", "age": "年龄4" }, { "name": "姓名5", "age": "年龄5" }, { "name": "姓名6", "age": "年龄6" } ], "pagination": { "total": 10, "currentPage": 2, "prePageCount": 3 } }
如果你有更好的方案,欢迎留言评论 ~