diff --git a/library/think/model/Relation.php b/library/think/model/Relation.php index d7938836..22223281 100644 --- a/library/think/model/Relation.php +++ b/library/think/model/Relation.php @@ -11,6 +11,8 @@ namespace think\model; +use think\db\Query; + abstract class Relation { // 父模型对象 @@ -31,6 +33,8 @@ abstract class Relation protected $where; // 关联查询参数 protected $option; + // 基础查询 + protected $baseQuery; /** * 获取关联的所属模型 @@ -77,12 +81,16 @@ abstract class Relation public function __call($method, $args) { if ($this->query) { + // 执行基础查询 + $this->baseQuery(); + $result = call_user_func_array([$this->query, $method], $args); - if ($result instanceof \think\db\Query) { + if ($result instanceof Query) { $this->option = $result->getOptions(); return $this; } else { - $this->option = []; + $this->option = []; + $this->baseQuery = false; return $result; } } else { diff --git a/library/think/model/relation/BelongsTo.php b/library/think/model/relation/BelongsTo.php index ae5c400e..ffab752d 100644 --- a/library/think/model/relation/BelongsTo.php +++ b/library/think/model/relation/BelongsTo.php @@ -11,13 +11,10 @@ namespace think\model\relation; -use think\Db; -use think\db\Query; -use think\Loader; use think\Model; -use think\model\Relation; +use think\model\relation\OneToOne; -class BelongsTo extends Relation +class BelongsTo extends OneToOne { /** * 架构函数 @@ -40,7 +37,10 @@ class BelongsTo extends Relation $this->query = (new $model)->db(); } - // 动态获取关联数据 + /** + * 延迟获取关联数据 + * @access public + */ public function getRelation() { $foreignKey = $this->foreignKey; @@ -48,124 +48,4 @@ class BelongsTo extends Relation return $this->query->where($localKey, $this->parent->$foreignKey)->find(); } - /** - * 预载入关联查询 - * @access public - * @param Query $query 查询对象 - * @param string $relation 关联名 - * @return void - */ - public function eagerly(Query $query, $relation, $subRelation, $closure, $first) - { - $name = Loader::parseName(basename(str_replace('\\', '/', $query->getModel()))); - $alias = isset($this->alias[$name]) ? $this->alias[$name] : $name; - if ($first) { - - $table = $query->getTable(); - $query->table([$table => $alias]); - if ($query->getOptions('field')) { - $field = $query->getOptions('field'); - $query->removeOption('field'); - } else { - $field = true; - } - $query->field($field, false, $table, $alias); - } - - // 预载入封装 - $joinTable = $this->query->getTable(); - $joinName = Loader::parseName(basename(str_replace('\\', '/', $this->model))); - $joinAlias = isset($this->alias[$joinName]) ? $this->alias[$joinName] : $relation; - $query->via($joinAlias); - - $query->join($joinTable . ' ' . $joinAlias, $alias . '.' . $this->foreignKey . '=' . $joinAlias . '.' . $this->localKey, $this->joinType); - - if ($closure) { - // 执行闭包查询 - call_user_func_array($closure, [ & $query]); - //指定获取关联的字段 - //需要在 回调中 调方法 withField 方法,如 - // $query->where(['id'=>1])->withField('id,name'); - if ($query->getOptions('with_field')) { - $field = $query->getOptions('with_field'); - $query->removeOption('with_field'); - } - } elseif (isset($this->option['field'])) { - $field = $this->option['field']; - } else { - $field = true; - } - $query->field($field, false, $joinTable, $joinAlias, $relation . '__'); - } - - /** - * 预载入关联查询 返回数据集 - * @access public - * @param array $resultSet 数据集 - * @param string $relation 关联名 - * @param string $class 数据集对象名 为空表示数组 - * @return array - */ - public function eagerlyResultSet(&$resultSet, $relation) - { - foreach ($resultSet as $result) { - // 模型关联组装 - $this->match($this->model, $relation, $result); - } - } - - /** - * 预载入关联查询 返回模型对象 - * @access public - * @param Model $result 数据对象 - * @param string $relation 关联名 - * @param string $class 数据集对象名 为空表示数组 - * @return Model - */ - public function eagerlyResult(&$result, $relation) - { - // 模型关联组装 - $this->match($this->model, $relation, $result); - } - - /** - * 一对一 关联模型预查询拼装 - * @access public - * @param string $model 模型名称 - * @param string $relation 关联名 - * @param Model $result 模型对象实例 - * @return void - */ - protected function match($model, $relation, &$result) - { - // 重新组装模型数据 - foreach ($result->getData() as $key => $val) { - if (strpos($key, '__')) { - list($name, $attr) = explode('__', $key, 2); - if ($name == $relation) { - $list[$name][$attr] = $val; - unset($result->$key); - } - } - } - - $result->setAttr($relation, !isset($list[$relation]) ? null : (new $model($list[$relation]))->isUpdate(true)); - } - - /** - * 保存(新增)当前关联数据对象 - * @access public - * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键 - * @return integer - */ - public function save($data) - { - if ($data instanceof Model) { - $data = $data->getData(); - } - // 保存关联表数据 - $data[$this->foreignKey] = $this->parent->{$this->localKey}; - $model = new $this->model; - return $model->save($data); - } } diff --git a/library/think/model/relation/BelongsToMany.php b/library/think/model/relation/BelongsToMany.php index 59220aee..ccb43be4 100644 --- a/library/think/model/relation/BelongsToMany.php +++ b/library/think/model/relation/BelongsToMany.php @@ -43,7 +43,10 @@ class BelongsToMany extends Relation $this->query = (new $model)->db(); } - // 动态获取关联数据 + /** + * 延迟获取关联数据 + * @access public + */ public function getRelation() { $foreignKey = $this->foreignKey; @@ -70,25 +73,14 @@ class BelongsToMany extends Relation } /** - * 预载入关联查询 - * @access public - * @param Query $query 查询对象 - * @param string $relation 关联名 - * @param bool $first 是否需要使用基础表 - * @return void - */ - public function eagerly(Query $query, $relation, $subRelation, $closure, $first) - { - - } - - /** - * 预载入关联查询 返回数据集 + * 预载入关联查询(数据集) * @access public * @param array $resultSet 数据集 - * @param string $relation 关联名 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 * @param string $class 数据集对象名 为空表示数组 - * @return array + * @return void */ public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class) { @@ -125,12 +117,14 @@ class BelongsToMany extends Relation } /** - * 预载入关联查询 返回模型对象 + * 预载入关联查询(单个数据) * @access public * @param Model $result 数据对象 - * @param string $relation 关联名 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 * @param string $class 数据集对象名 为空表示数组 - * @return Model + * @return void */ public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class) { @@ -304,27 +298,18 @@ class BelongsToMany extends Relation } } - public function __call($method, $args) + /** + * 执行基础查询(进执行一次) + * @access protected + * @return void + */ + protected function baseQuery() { - static $baseQuery = false; - if ($this->query) { - if (empty($baseQuery)) { - $baseQuery = true; - $pk = $this->parent->getPk(); - $this->query->join($this->middle . ' pivot', 'pivot.' . $this->foreignKey . '=' . $this->query->getTable() . '.' . $this->query->getPk())->where('pivot.' . $this->localKey, $this->parent->$pk); - } - - $result = call_user_func_array([$this->query, $method], $args); - if ($result instanceof \think\db\Query) { - $this->option = $result->getOptions(); - return $this; - } else { - $this->option = []; - $baseQuery = false; - return $result; - } - } else { - throw new Exception('method not exists:' . __CLASS__ . '->' . $method); + if (empty($this->baseQuery)) { + $pk = $this->parent->getPk(); + $this->query->join($this->middle . ' pivot', 'pivot.' . $this->foreignKey . '=' . $this->query->getTable() . '.' . $this->query->getPk())->where('pivot.' . $this->localKey, $this->parent->$pk); + $this->baseQuery = true; } } + } diff --git a/library/think/model/relation/HasMany.php b/library/think/model/relation/HasMany.php index 5c7d129a..7d73e3a2 100644 --- a/library/think/model/relation/HasMany.php +++ b/library/think/model/relation/HasMany.php @@ -37,7 +37,10 @@ class HasMany extends Relation $this->query = (new $model)->db(); } - // 动态获取关联数据 + /** + * 延迟获取关联数据 + * @access public + */ public function getRelation() { return $this->select(); @@ -46,23 +49,12 @@ class HasMany extends Relation /** * 预载入关联查询 * @access public - * @param Query $query 查询对象 - * @param string $relation 关联名 - * @param bool $first 是否需要使用基础表 - * @return void - */ - public function eagerly(Query $query, $relation, $subRelation, $closure, $first) - { - - } - - /** - * 预载入关联查询 返回数据集 - * @access public * @param array $resultSet 数据集 - * @param string $relation 关联名 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 * @param string $class 数据集对象名 为空表示数组 - * @return array + * @return void */ public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class) { @@ -97,12 +89,14 @@ class HasMany extends Relation } /** - * 预载入关联查询 返回模型对象 + * 预载入关联查询 * @access public * @param Model $result 数据对象 - * @param string $relation 关联名 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 * @param string $class 数据集对象名 为空表示数组 - * @return Model + * @return void */ public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class) { @@ -221,31 +215,22 @@ class HasMany extends Relation ->where($where); } - public function __call($method, $args) + /** + * 执行基础查询(进执行一次) + * @access protected + * @return void + */ + protected function baseQuery() { - static $baseQuery = false; - if ($this->query) { - if (empty($baseQuery)) { - $baseQuery = true; - if (isset($this->where)) { - $this->query->where($this->where); - } elseif (isset($this->parent->{$this->localKey})) { - // 关联查询带入关联条件 - $this->query->where($this->foreignKey, $this->parent->{$this->localKey}); - } + if (empty($this->baseQuery)) { + if (isset($this->where)) { + $this->query->where($this->where); + } elseif (isset($this->parent->{$this->localKey})) { + // 关联查询带入关联条件 + $this->query->where($this->foreignKey, $this->parent->{$this->localKey}); } - - $result = call_user_func_array([$this->query, $method], $args); - if ($result instanceof \think\db\Query) { - $this->option = $result->getOptions(); - return $this; - } else { - $this->option = []; - $baseQuery = false; - return $result; - } - } else { - throw new Exception('method not exists:' . __CLASS__ . '->' . $method); + $this->baseQuery = true; } } + } diff --git a/library/think/model/relation/HasManyThrough.php b/library/think/model/relation/HasManyThrough.php index 2661b7b3..9f4c0431 100644 --- a/library/think/model/relation/HasManyThrough.php +++ b/library/think/model/relation/HasManyThrough.php @@ -45,7 +45,10 @@ class HasManyThrough extends Relation $this->query = (new $model)->db(); } - // 动态获取关联数据 + /** + * 延迟获取关联数据 + * @access public + */ public function getRelation() { return $this->select(); @@ -65,12 +68,14 @@ class HasManyThrough extends Relation } /** - * 预载入关联查询 返回数据集 + * 预载入关联查询 * @access public * @param array $resultSet 数据集 - * @param string $relation 关联名 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 * @param string $class 数据集对象名 为空表示数组 - * @return array + * @return void */ public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class) { @@ -81,45 +86,38 @@ class HasManyThrough extends Relation * 预载入关联查询 返回模型对象 * @access public * @param Model $result 数据对象 - * @param string $relation 关联名 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 * @param string $class 数据集对象名 为空表示数组 - * @return Model + * @return void */ public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class) { } - public function __call($method, $args) + /** + * 执行基础查询(进执行一次) + * @access protected + * @return void + */ + protected function baseQuery() { - static $baseQuery = false; - if ($this->query) { - if (empty($baseQuery)) { - $baseQuery = true; - $through = $this->middle; - $model = $this->model; - $alias = Loader::parseName(basename(str_replace('\\', '/', $model))); - $throughTable = $through::getTable(); - $pk = (new $this->model)->getPk(); - $throughKey = $this->throughKey; - $modelTable = $this->parent->getTable(); - $this->query->field($alias . '.*')->alias($alias) - ->join($throughTable, $throughTable . '.' . $pk . '=' . $alias . '.' . $throughKey) - ->join($modelTable, $modelTable . '.' . $this->localKey . '=' . $throughTable . '.' . $this->foreignKey) - ->where($throughTable . '.' . $this->foreignKey, $this->parent->{$this->localKey}); - } - - $result = call_user_func_array([$this->query, $method], $args); - if ($result instanceof \think\db\Query) { - $this->option = $result->getOptions(); - return $this; - } else { - $this->option = []; - $baseQuery = false; - return $result; - } - } else { - throw new Exception('method not exists:' . __CLASS__ . '->' . $method); + if (empty($this->baseQuery)) { + $through = $this->middle; + $model = $this->model; + $alias = Loader::parseName(basename(str_replace('\\', '/', $model))); + $throughTable = $through::getTable(); + $pk = (new $this->model)->getPk(); + $throughKey = $this->throughKey; + $modelTable = $this->parent->getTable(); + $this->query->field($alias . '.*')->alias($alias) + ->join($throughTable, $throughTable . '.' . $pk . '=' . $alias . '.' . $throughKey) + ->join($modelTable, $modelTable . '.' . $this->localKey . '=' . $throughTable . '.' . $this->foreignKey) + ->where($throughTable . '.' . $this->foreignKey, $this->parent->{$this->localKey}); + $this->baseQuery = true; } } + } diff --git a/library/think/model/relation/HasOne.php b/library/think/model/relation/HasOne.php index c7b71c53..85ac237e 100644 --- a/library/think/model/relation/HasOne.php +++ b/library/think/model/relation/HasOne.php @@ -11,13 +11,10 @@ namespace think\model\relation; -use think\Db; -use think\db\Query; -use think\Loader; use think\Model; -use think\model\Relation; +use think\model\relation\OneToOne; -class HasOne extends Relation +class HasOne extends OneToOne { /** * 架构函数 @@ -40,7 +37,10 @@ class HasOne extends Relation $this->query = (new $model)->db(); } - // 动态获取关联数据 + /** + * 延迟获取关联数据 + * @access public + */ public function getRelation() { // 执行关联定义方法 @@ -50,125 +50,4 @@ class HasOne extends Relation return $this->query->where($this->foreignKey, $this->parent->$localKey)->find(); } - /** - * 预载入关联查询 - * @access public - * @param Query $query 查询对象 - * @param string $relation 关联名 - * @return void - */ - public function eagerly(Query $query, $relation, $subRelation, &$closure, $first) - { - $name = Loader::parseName(basename(str_replace('\\', '/', $query->getModel()))); - $alias = isset($this->alias[$name]) ? $this->alias[$name] : $name; - if ($first) { - $table = $query->getTable(); - $query->table([$table => $alias]); - if ($query->getOptions('field')) { - $field = $query->getOptions('field'); - $query->removeOption('field'); - } else { - $field = true; - } - $query->field($field, false, $table, $alias); - - } - - // 预载入封装 - $joinTable = $this->query->getTable(); - $joinName = Loader::parseName(basename(str_replace('\\', '/', $this->model))); - $joinAlias = isset($this->alias[$joinName]) ? $this->alias[$joinName] : $relation; - $query->via($joinAlias); - - $query->join($joinTable . ' ' . $joinAlias, $alias . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey, $this->joinType); - - if ($closure) { - // 执行闭包查询 - call_user_func_array($closure, [ & $query]); - //指定获取关联的字段 - //需要在 回调中 调方法 withField 方法,如 - // $query->where(['id'=>1])->withField('id,name'); - if ($query->getOptions('with_field')) { - $field = $query->getOptions('with_field'); - $query->removeOption('with_field'); - } - $closure = null; - } elseif (isset($this->option['field'])) { - $field = $this->option['field']; - } else { - $field = true; - } - $query->field($field, false, $joinTable, $joinAlias, $relation . '__'); - } - - /** - * 预载入关联查询 返回数据集 - * @access public - * @param array $resultSet 数据集 - * @param string $relation 关联名 - * @param string $class 数据集对象名 为空表示数组 - * @return array - */ - public function eagerlyResultSet(&$resultSet, $relation) - { - foreach ($resultSet as $result) { - // 模型关联组装 - $this->match($this->model, $relation, $result); - } - } - - /** - * 预载入关联查询 返回模型对象 - * @access public - * @param Model $result 数据对象 - * @param string $relation 关联名 - * @param string $class 数据集对象名 为空表示数组 - * @return Model - */ - public function eagerlyResult(&$result, $relation) - { - // 模型关联组装 - $this->match($this->model, $relation, $result); - } - - /** - * 一对一 关联模型预查询拼装 - * @access public - * @param string $model 模型名称 - * @param string $relation 关联名 - * @param Model $result 模型对象实例 - * @return void - */ - protected function match($model, $relation, &$result) - { - // 重新组装模型数据 - foreach ($result->getData() as $key => $val) { - if (strpos($key, '__')) { - list($name, $attr) = explode('__', $key, 2); - if ($name == $relation) { - $list[$name][$attr] = $val; - unset($result->$key); - } - } - } - - $result->setAttr($relation, !isset($list[$relation]) ? null : (new $model($list[$relation]))->isUpdate(true)); - } - - /** - * 保存(新增)当前关联数据对象 - * @access public - * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键 - * @return integer - */ - public function save($data) - { - if ($data instanceof Model) { - $data = $data->getData(); - } - // 保存关联表数据 - $data[$this->foreignKey] = $this->parent->{$this->localKey}; - $model = new $this->model; - return $model->save($data); - } } diff --git a/library/think/model/relation/MorphMany.php b/library/think/model/relation/MorphMany.php index 9d6371ba..cfce9b57 100644 --- a/library/think/model/relation/MorphMany.php +++ b/library/think/model/relation/MorphMany.php @@ -43,7 +43,10 @@ class MorphMany extends Relation $this->query = (new $model)->db(); } - // 动态获取关联数据 + /** + * 延迟获取关联数据 + * @access public + */ public function getRelation() { return $this->select(); @@ -52,23 +55,12 @@ class MorphMany extends Relation /** * 预载入关联查询 * @access public - * @param Query $query 查询对象 - * @param string $relation 关联名 - * @param bool $first 是否需要使用基础表 - * @return void - */ - public function eagerly(Query $query, $relation, $subRelation, $closure, $first) - { - - } - - /** - * 预载入关联查询 返回数据集 - * @access public * @param array $resultSet 数据集 - * @param string $relation 关联名 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 * @param string $class 数据集对象名 为空表示数组 - * @return array + * @return void */ public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class) { @@ -103,12 +95,14 @@ class MorphMany extends Relation } /** - * 预载入关联查询 返回模型对象 + * 预载入关联查询 * @access public * @param Model $result 数据对象 - * @param string $relation 关联名 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 * @param string $class 数据集对象名 为空表示数组 - * @return Model + * @return void */ public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class) { @@ -147,29 +141,20 @@ class MorphMany extends Relation return $data; } - public function __call($method, $args) + /** + * 执行基础查询(进执行一次) + * @access protected + * @return void + */ + protected function baseQuery() { - static $baseQuery = false; - if ($this->query) { - if (empty($baseQuery)) { - $baseQuery = true; - $pk = $this->parent->getPk(); - $map[$this->morphKey] = $this->parent->$pk; - $map[$this->morphType] = $this->type; - $this->query->where($map); - } - - $result = call_user_func_array([$this->query, $method], $args); - if ($result instanceof \think\db\Query) { - $this->option = $result->getOptions(); - return $this; - } else { - $this->option = []; - $baseQuery = false; - return $result; - } - } else { - throw new Exception('method not exists:' . __CLASS__ . '->' . $method); + if (empty($this->baseQuery)) { + $pk = $this->parent->getPk(); + $map[$this->morphKey] = $this->parent->$pk; + $map[$this->morphType] = $this->type; + $this->query->where($map); + $this->baseQuery = true; } } + } diff --git a/library/think/model/relation/MorphTo.php b/library/think/model/relation/MorphTo.php index 0d55d2e4..2b370e08 100644 --- a/library/think/model/relation/MorphTo.php +++ b/library/think/model/relation/MorphTo.php @@ -11,7 +11,6 @@ namespace think\model\relation; -use think\db\Query; use think\Loader; use think\Model; use think\model\Relation; @@ -38,7 +37,10 @@ class MorphTo extends Relation $this->alias = $alias; } - // 动态获取关联数据 + /** + * 延迟获取关联数据 + * @access public + */ public function getRelation() { $morphKey = $this->morphKey; @@ -70,19 +72,6 @@ class MorphTo extends Relation return $model; } - /** - * 预载入关联查询 - * @access public - * @param Query $query 查询对象 - * @param string $relation 关联名 - * @param bool $first 是否需要使用基础表 - * @return void - */ - public function eagerly(Query $query, $relation, $subRelation, $closure, $first) - { - - } - /** * 预载入关联查询 返回数据集 * @access public @@ -163,4 +152,12 @@ class MorphTo extends Relation $result->setAttr($relation, $data ?: null); } + /** + * 执行基础查询(进执行一次) + * @access protected + * @return void + */ + protected function baseQuery() + { + } } diff --git a/library/think/model/relation/OneToOne.php b/library/think/model/relation/OneToOne.php new file mode 100644 index 00000000..650000e9 --- /dev/null +++ b/library/think/model/relation/OneToOne.php @@ -0,0 +1,161 @@ + +// +---------------------------------------------------------------------- + +namespace think\model\relation; + +use think\db\Query; +use think\Loader; +use think\Model; +use think\model\Relation; +use think\model\relation\BelongsTo; + +abstract class OneToOne extends Relation +{ + /** + * 预载入关联查询 + * @access public + * @param Query $query 查询对象 + * @param string $relation 关联名 + * @param string $subRelation 子关联 + * @param \Closure $closure 闭包条件 + * @param bool $first + * @return void + */ + public function eagerly(Query $query, $relation, $subRelation, $closure, $first) + { + $name = Loader::parseName(basename(str_replace('\\', '/', $query->getModel()))); + $alias = isset($this->alias[$name]) ? $this->alias[$name] : $name; + if ($first) { + $table = $query->getTable(); + $query->table([$table => $alias]); + if ($query->getOptions('field')) { + $field = $query->getOptions('field'); + $query->removeOption('field'); + } else { + $field = true; + } + $query->field($field, false, $table, $alias); + } + + // 预载入封装 + $joinTable = $this->query->getTable(); + $joinName = Loader::parseName(basename(str_replace('\\', '/', $this->model))); + $joinAlias = isset($this->alias[$joinName]) ? $this->alias[$joinName] : $relation; + $query->via($joinAlias); + + if ($this instanceof BelongsTo) { + $query->join($joinTable . ' ' . $joinAlias, $alias . '.' . $this->foreignKey . '=' . $joinAlias . '.' . $this->localKey, $this->joinType); + } else { + $query->join($joinTable . ' ' . $joinAlias, $alias . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey, $this->joinType); + } + + if ($closure) { + // 执行闭包查询 + call_user_func_array($closure, [ & $query]); + //指定获取关联的字段 + //需要在 回调中 调方法 withField 方法,如 + // $query->where(['id'=>1])->withField('id,name'); + if ($query->getOptions('with_field')) { + $field = $query->getOptions('with_field'); + $query->removeOption('with_field'); + } + } elseif (isset($this->option['field'])) { + $field = $this->option['field']; + } else { + $field = true; + } + $query->field($field, false, $joinTable, $joinAlias, $relation . '__'); + } + + /** + * 预载入关联查询 + * @access public + * @param array $resultSet 数据集 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @param string $class 数据集对象名 为空表示数组 + * @return void + */ + public function eagerlyResultSet(&$resultSet, $relation) + { + foreach ($resultSet as $result) { + // 模型关联组装 + $this->match($this->model, $relation, $result); + } + } + + /** + * 预载入关联查询 返回模型对象 + * @access public + * @param Model $result 数据对象 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @param string $class 数据集对象名 为空表示数组 + * @return void + */ + public function eagerlyResult(&$result, $relation) + { + // 模型关联组装 + $this->match($this->model, $relation, $result); + } + + /** + * 一对一 关联模型预查询拼装 + * @access public + * @param string $model 模型名称 + * @param string $relation 关联名 + * @param Model $result 模型对象实例 + * @return void + */ + protected function match($model, $relation, &$result) + { + // 重新组装模型数据 + foreach ($result->getData() as $key => $val) { + if (strpos($key, '__')) { + list($name, $attr) = explode('__', $key, 2); + if ($name == $relation) { + $list[$name][$attr] = $val; + unset($result->$key); + } + } + } + + $result->setAttr($relation, !isset($list[$relation]) ? null : (new $model($list[$relation]))->isUpdate(true)); + } + + /** + * 保存(新增)当前关联数据对象 + * @access public + * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键 + * @return integer + */ + public function save($data) + { + if ($data instanceof Model) { + $data = $data->getData(); + } + // 保存关联表数据 + $data[$this->foreignKey] = $this->parent->{$this->localKey}; + $model = new $this->model; + return $model->save($data); + } + + /** + * 执行基础查询(进执行一次) + * @access protected + * @return void + */ + protected function baseQuery() + { + } +}