提交 90935273 编写于 作者: weixin_47267244's avatar weixin_47267244

支持 MySQL 高性能分页查询(大表分页类)

上级 90b1f283
......@@ -722,6 +722,30 @@ var_dump(json_encode($data)); // 支持序列化
]
```
### 高性能分页查询
```php
// 首先准备好查询构建器
$query = Db::query()->from('xxxtable');
// 实例化大表分页类,字段名默认 id
$pagination = new \Imi\Db\Mysql\Query\Pagination\BigTablePagination($query);
// 指定主表主键字段名,如果涉及多张表关联,这里需要指定主表的主键字段名
$pagination = new \Imi\Db\Mysql\Query\Pagination\BigTablePagination($query, 'xxxtable.id');
// 只查列表,返回值同 $query->select(),Result 对象
$result = $pagination->select();
// 获取数组
$result->getArray();
// 分页查询,返回值同 $query->paginate(),PaginationResult 对象
$page = 1;
$limit = 10;
$result = $pagination->paginate($page, $limit);
```
> 仅 MySQL 数据库支持
## 查询执行
### 查询记录
......
<?php
declare(strict_types=1);
namespace Imi\Db\Mysql\Query\Pagination;
use Imi\Db\Query\Interfaces\IPaginateResult;
use Imi\Db\Query\Interfaces\IQuery;
use Imi\Db\Query\Interfaces\IResult;
use Imi\Db\Query\PaginateResult;
use Imi\Util\Pagination;
class BigTablePagination
{
protected IQuery $query;
protected string $idField = '';
public function __construct(IQuery $query, string $idField = 'id')
{
$this->query = $query;
$this->idField = $idField;
}
public function getQuery(): IQuery
{
return $this->query;
}
public function paginate(int $page, int $limit, array $options = []): IPaginateResult
{
if ($options['total'] ?? true)
{
$query = clone $this->query;
$option = $query->getOption();
$option->order = [];
$total = (int) $query->count();
}
else
{
$total = null;
}
$pagination = new Pagination($page, $limit);
$query = clone $this->query;
return new PaginateResult($this->select($page, $limit), $pagination->getLimitOffset(), $limit, $total, null === $total ? null : $pagination->calcPageCount($total), $options);
}
public function select(int $page, int $limit): IResult
{
$query = clone $this->query;
$ids = $query->field($this->idField)->page($page, $limit)->select()->getColumn();
$query = clone $this->query;
return $query->whereIn($this->idField, $ids)->select();
}
}
......@@ -8,6 +8,7 @@ use Imi\Db\Db;
use Imi\Db\Mysql\Query\FullText\MysqlFullTextOptions;
use Imi\Db\Mysql\Query\FullText\SearchModifier;
use Imi\Db\Mysql\Query\Lock\MysqlLock;
use Imi\Db\Mysql\Query\Pagination\BigTablePagination;
use Imi\Db\Query\Database;
use Imi\Db\Query\Raw;
use Imi\Db\Query\Where\Where;
......@@ -187,6 +188,37 @@ abstract class QueryCurdBaseTest extends BaseTest
$this->assertEquals($expectedData['page_count'], $result->getPageCount());
}
/**
* @depends testInsert
*/
public function testBigTablePagination(array $args): void
{
['ids' => $ids] = $args;
$expectedData = [
'list' => [
[
'id' => $ids[1],
'title' => 'title-insert',
'content' => 'content-insert',
'time' => '2019-06-21 00:00:00',
'member_id' => 0,
],
],
'limit' => 1,
'total' => 2,
'page_count' => 2,
];
$query = Db::query($this->poolName)->from($this->tableArticle);
$pagination = new BigTablePagination($query);
$this->assertEquals($expectedData, $pagination->select(2, 1)->getArray());
$result = $pagination->paginate(2, 1);
$this->assertEquals($expectedData, $result->toArray());
$this->assertEquals($expectedData['list'], $result->getList());
$this->assertEquals($expectedData['total'], $result->getTotal());
$this->assertEquals($expectedData['limit'], $result->getLimit());
$this->assertEquals($expectedData['page_count'], $result->getPageCount());
}
/**
* @depends testInsert
*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册