关联预载入查询支持关联统计

This commit is contained in:
thinkphp
2016-12-22 12:52:13 +08:00
parent cd57d97f36
commit 9657ee01b1
5 changed files with 52 additions and 16 deletions

View File

@@ -1261,9 +1261,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
* @param array $resultSet 数据集 * @param array $resultSet 数据集
* @param string $relation 关联名 * @param string $relation 关联名
* @param string $class 数据集对象名 为空表示数组 * @param string $class 数据集对象名 为空表示数组
* @param bool $count 是否统计
* @return array * @return array
*/ */
public function eagerlyResultSet(&$resultSet, $relation, $class = '') public function eagerlyResultSet(&$resultSet, $relation, $class = '', $count = false)
{ {
$relations = is_string($relation) ? explode(',', $relation) : $relation; $relations = is_string($relation) ? explode(',', $relation) : $relation;
foreach ($relations as $key => $relation) { foreach ($relations as $key => $relation) {
@@ -1277,7 +1278,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
list($relation, $subRelation) = explode('.', $relation); list($relation, $subRelation) = explode('.', $relation);
} }
$relation = Loader::parseName($relation, 1, false); $relation = Loader::parseName($relation, 1, false);
$this->$relation()->eagerlyResultSet($resultSet, $relation, $subRelation, $closure, $class); $this->$relation()->eagerlyResultSet($resultSet, $relation, $subRelation, $closure, $class, $count);
} }
} }
@@ -1287,9 +1288,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
* @param Model $result 数据对象 * @param Model $result 数据对象
* @param string $relation 关联名 * @param string $relation 关联名
* @param string $class 数据集对象名 为空表示数组 * @param string $class 数据集对象名 为空表示数组
* @param bool $count 是否统计
* @return Model * @return Model
*/ */
public function eagerlyResult(&$result, $relation, $class = '') public function eagerlyResult(&$result, $relation, $class = '', $count = false)
{ {
$relations = is_string($relation) ? explode(',', $relation) : $relation; $relations = is_string($relation) ? explode(',', $relation) : $relation;
@@ -1304,7 +1306,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
list($relation, $subRelation) = explode('.', $relation); list($relation, $subRelation) = explode('.', $relation);
} }
$relation = Loader::parseName($relation, 1, false); $relation = Loader::parseName($relation, 1, false);
$this->$relation()->eagerlyResult($result, $relation, $subRelation, $closure, $class); $this->$relation()->eagerlyResult($result, $relation, $subRelation, $closure, $class, $count);
} }
} }

View File

@@ -1621,9 +1621,10 @@ class Query
* 设置关联查询JOIN预查询 * 设置关联查询JOIN预查询
* @access public * @access public
* @param string|array $with 关联方法名称 * @param string|array $with 关联方法名称
* @param bool $count 是否统计
* @return $this * @return $this
*/ */
public function with($with) public function with($with, $count = false)
{ {
if (empty($with)) { if (empty($with)) {
return $this; return $this;
@@ -1663,6 +1664,7 @@ class Query
} }
$this->via(); $this->via();
$this->options['with'] = $with; $this->options['with'] = $with;
$this->options['count'] = $count;
return $this; return $this;
} }
@@ -2017,7 +2019,7 @@ class Query
} }
if (!empty($options['with'])) { if (!empty($options['with'])) {
// 预载入 // 预载入
$result->eagerlyResultSet($resultSet, $options['with'], is_object($resultSet) ? get_class($resultSet) : ''); $result->eagerlyResultSet($resultSet, $options['with'], is_object($resultSet) ? get_class($resultSet) : '', !empty($options['count']) ? true : false);
} }
} }
// 模型数据集转换 // 模型数据集转换
@@ -2113,7 +2115,7 @@ class Query
} }
// 预载入查询 // 预载入查询
if (!empty($options['with'])) { if (!empty($options['with'])) {
$data->eagerlyResult($data, $options['with'], is_object($result) ? get_class($result) : ''); $data->eagerlyResult($data, $options['with'], is_object($result) ? get_class($result) : '', !empty($options['count']) ? true : false);
} }
// 关联统计 // 关联统计
if (!empty($options['with_count'])) { if (!empty($options['with_count'])) {

View File

@@ -13,6 +13,7 @@ namespace think\model\relation;
use think\Db; use think\Db;
use think\db\Query; use think\db\Query;
use think\Loader;
use think\Model; use think\Model;
use think\model\Pivot; use think\model\Pivot;
use think\model\Relation; use think\model\Relation;
@@ -80,9 +81,10 @@ class BelongsToMany extends Relation
* @param string $subRelation 子关联名 * @param string $subRelation 子关联名
* @param \Closure $closure 闭包 * @param \Closure $closure 闭包
* @param string $class 数据集对象名 为空表示数组 * @param string $class 数据集对象名 为空表示数组
* @param bool $count 是否统计
* @return void * @return void
*/ */
public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class) public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class, $count)
{ {
$localKey = $this->localKey; $localKey = $this->localKey;
$foreignKey = $this->foreignKey; $foreignKey = $this->foreignKey;
@@ -110,7 +112,10 @@ class BelongsToMany extends Relation
if (!isset($data[$result->$pk])) { if (!isset($data[$result->$pk])) {
$data[$result->$pk] = []; $data[$result->$pk] = [];
} }
if ($count) {
// 关联统计
$result->setAttr(Loader::parseName($relation) . '_count', count($data[$result->$pk]));
}
$result->setAttr($relation, $this->resultSetBuild($data[$result->$pk], $class)); $result->setAttr($relation, $this->resultSetBuild($data[$result->$pk], $class));
} }
} }
@@ -124,9 +129,10 @@ class BelongsToMany extends Relation
* @param string $subRelation 子关联名 * @param string $subRelation 子关联名
* @param \Closure $closure 闭包 * @param \Closure $closure 闭包
* @param string $class 数据集对象名 为空表示数组 * @param string $class 数据集对象名 为空表示数组
* @param bool $count 是否统计
* @return void * @return void
*/ */
public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class) public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class, $count)
{ {
$localKey = $this->localKey; $localKey = $this->localKey;
$foreignKey = $this->foreignKey; $foreignKey = $this->foreignKey;
@@ -141,6 +147,10 @@ class BelongsToMany extends Relation
if (!isset($data[$pk])) { if (!isset($data[$pk])) {
$data[$pk] = []; $data[$pk] = [];
} }
if ($count) {
// 关联统计
$result->setAttr(Loader::parseName($relation) . '_count', count($data[$pk]));
}
$result->setAttr($relation, $this->resultSetBuild($data[$pk], $class)); $result->setAttr($relation, $this->resultSetBuild($data[$pk], $class));
} }
} }

View File

@@ -13,6 +13,7 @@ namespace think\model\relation;
use think\Db; use think\Db;
use think\db\Query; use think\db\Query;
use think\Loader;
use think\Model; use think\Model;
use think\model\Relation; use think\model\Relation;
@@ -54,9 +55,10 @@ class HasMany extends Relation
* @param string $subRelation 子关联名 * @param string $subRelation 子关联名
* @param \Closure $closure 闭包 * @param \Closure $closure 闭包
* @param string $class 数据集对象名 为空表示数组 * @param string $class 数据集对象名 为空表示数组
* @param bool $count 是否统计
* @return void * @return void
*/ */
public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class) public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class, $count)
{ {
$localKey = $this->localKey; $localKey = $this->localKey;
$foreignKey = $this->foreignKey; $foreignKey = $this->foreignKey;
@@ -83,6 +85,10 @@ class HasMany extends Relation
if (!isset($data[$result->$localKey])) { if (!isset($data[$result->$localKey])) {
$data[$result->$localKey] = []; $data[$result->$localKey] = [];
} }
if ($count) {
// 关联统计
$result->setAttr(Loader::parseName($relation) . '_count', count($data[$result->$localKey]));
}
$result->setAttr($relation, $this->resultSetBuild($data[$result->$localKey], $class)); $result->setAttr($relation, $this->resultSetBuild($data[$result->$localKey], $class));
} }
} }
@@ -96,9 +102,10 @@ class HasMany extends Relation
* @param string $subRelation 子关联名 * @param string $subRelation 子关联名
* @param \Closure $closure 闭包 * @param \Closure $closure 闭包
* @param string $class 数据集对象名 为空表示数组 * @param string $class 数据集对象名 为空表示数组
* @param bool $count 是否统计
* @return void * @return void
*/ */
public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class) public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class, $count)
{ {
$localKey = $this->localKey; $localKey = $this->localKey;
$foreignKey = $this->foreignKey; $foreignKey = $this->foreignKey;
@@ -109,6 +116,10 @@ class HasMany extends Relation
if (!isset($data[$result->$localKey])) { if (!isset($data[$result->$localKey])) {
$data[$result->$localKey] = []; $data[$result->$localKey] = [];
} }
if ($count) {
// 关联统计
$result->setAttr(Loader::parseName($relation) . '_count', count($data[$result->$localKey]));
}
$result->setAttr($relation, $this->resultSetBuild($data[$result->$localKey], $class)); $result->setAttr($relation, $this->resultSetBuild($data[$result->$localKey], $class));
} }
} }

View File

@@ -13,6 +13,7 @@ namespace think\model\relation;
use think\Db; use think\Db;
use think\db\Query; use think\db\Query;
use think\Loader;
use think\Model; use think\Model;
use think\model\Relation; use think\model\Relation;
@@ -60,9 +61,10 @@ class MorphMany extends Relation
* @param string $subRelation 子关联名 * @param string $subRelation 子关联名
* @param \Closure $closure 闭包 * @param \Closure $closure 闭包
* @param string $class 数据集对象名 为空表示数组 * @param string $class 数据集对象名 为空表示数组
* @param bool $count 是否统计
* @return void * @return void
*/ */
public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class) public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class, $count)
{ {
$morphType = $this->morphType; $morphType = $this->morphType;
$morphKey = $this->morphKey; $morphKey = $this->morphKey;
@@ -89,6 +91,10 @@ class MorphMany extends Relation
if (!isset($data[$result->$pk])) { if (!isset($data[$result->$pk])) {
$data[$result->$pk] = []; $data[$result->$pk] = [];
} }
if ($count) {
// 关联统计
$result->setAttr(Loader::parseName($relation) . '_count', count($data[$result->$pk]));
}
$result->setAttr($relation, $this->resultSetBuild($data[$result->$pk], $class)); $result->setAttr($relation, $this->resultSetBuild($data[$result->$pk], $class));
} }
} }
@@ -102,9 +108,10 @@ class MorphMany extends Relation
* @param string $subRelation 子关联名 * @param string $subRelation 子关联名
* @param \Closure $closure 闭包 * @param \Closure $closure 闭包
* @param string $class 数据集对象名 为空表示数组 * @param string $class 数据集对象名 为空表示数组
* @param bool $count 是否统计
* @return void * @return void
*/ */
public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class) public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class, $count)
{ {
$morphType = $this->morphType; $morphType = $this->morphType;
$morphKey = $this->morphKey; $morphKey = $this->morphKey;
@@ -112,6 +119,10 @@ class MorphMany extends Relation
$pk = $result->getPk(); $pk = $result->getPk();
if (isset($result->$pk)) { if (isset($result->$pk)) {
$data = $this->eagerlyMorphToMany([$morphKey => $result->$pk, $morphType => $type], $relation, $subRelation, $closure); $data = $this->eagerlyMorphToMany([$morphKey => $result->$pk, $morphType => $type], $relation, $subRelation, $closure);
if ($count) {
// 关联统计
$result->setAttr(Loader::parseName($relation) . '_count', count($data[$result->$pk]));
}
$result->setAttr($relation, $this->resultSetBuild($data[$result->$pk], $class)); $result->setAttr($relation, $this->resultSetBuild($data[$result->$pk], $class));
} }
} }