这里只针对hasMany()进行封装,hasOne()等类似,假如有两张表,user(用户表),和order(订单表),我们要做的是统计每个用户订单里的fee字段的总和。
Query.php 添加
//统计求和
public function withSum($relation, $subQuery = true, $sum='sum')
{
if (!$subQuery) {
$this->options['with_sum'] = $relation;
} else {
$relations = is_string($relation) ? explode(',', $relation) : $relation;
if (!isset($this->options['field'])) {
$this->field('*');
}
foreach ($relations as $key => $relation) {
$closure = false;
if ($relation instanceof \Closure) {
$closure = $relation;
$relation = $key;
}
$relation = Loader::parseName($relation, 1, false);
$count = '(' . $this->model->$relation()->getRelationSumQuery($closure, $sum) . ')';
$this->field([$count => Loader::parseName($relation) . '_sum']);
}
}
return $this;
}
HasMany.php 添加:
public function getRelationSumQuery($closure, $sum)
{
if ($closure) {
call_user_func_array($closure, [ & $this->query]);
}
$localKey = $this->localKey ?: $this->parent->getPk();
return $this->query->whereExp($this->foreignKey, '=' . $this->parent->getTable() . '.' . $localKey)->fetchSql()->sum($sum);
}
调用方法:
$data = model('user')->withSum('order', 'fee')->select();
widthSum('order'),这里的order指的是模型里针对hasMany添加的一个方法。
public function order()
{
return $this->hasMany('Order');
}