diff --git a/library/think/Model.php b/library/think/Model.php index d3459365..570f1158 100644 --- a/library/think/Model.php +++ b/library/think/Model.php @@ -153,10 +153,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess throw new Exception('data type invalid', 10300); } $this->data = $data; - // 标记字段为更改 - foreach ($data as $key => $val) { - $this->change[] = $key; - } return $this; } @@ -740,6 +736,12 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return $this; } + /** + * 使用关联预载入查询 + * @access public + * @param string|array $relations 关联名 + * @return Db + */ public static function with($with = '') { if (is_string($with)) { @@ -750,7 +752,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return $db; } $class = new static(); - $joinName = basename(str_replace('\\', '/', static::class)); + $joinName = strtolower(basename(str_replace('\\', '/', static::class))); $joinTable = Db::name($joinName)->getTableName(); $db->table($joinTable)->alias($joinName)->field(true, false, $joinTable, $joinName); foreach ($with as $name) { @@ -759,14 +761,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess if (in_array($type, [self::HAS_ONE, self::BELONGS_TO])) { // 预载入封装 $table = $model::getTableName(); - $name = basename(str_replace('\\', '/', $model)); - $db->field($joinName . '.' . $localKey . ' as ' . $localKey) - ->join($table . ' ' . $name, $joinName . '.' . $localKey . '=' . $name . '.' . $foreignKey) - ->field(true, false, $table, $name); + $name = strtolower(basename(str_replace('\\', '/', $model))); + $db->join($table . ' ' . $name, $joinName . '.' . $localKey . '=' . $name . '.' . $foreignKey)->field(true, false, $table, $name); } } - return $db->with($with); - + return $db->with($with)->model(static::class); } /** @@ -778,49 +777,77 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ public function eagerly($resultSet, $relation) { - $relations = is_string($relation) ? explode(',', $relation) : $relation; foreach ($relations as $relation) { - $range = []; - $data = []; if (strpos($relation, '.')) { list($relation, $subRelation) = explode('.', $relation); } - $model = $this->$relation(); + // 执行关联方法 + $model = $this->$relation(); + // 获取关联信息 list($type, $foreignKey, $localKey) = $this->relation; - foreach ($resultSet as $result) { - // 获取关联外键列表 - $range[] = $result->$localKey; - } - // 预载入关联查询 - if (isset($subRelation)) { - // 嵌套预载入 - $list = $model::where($foreignKey, 'in', $range)->with($subRelation)->select(); - } else { - $list = $model::where($foreignKey, 'in', $range)->select(); - } + switch ($type) { case self::HAS_ONE: case self::BELONGS_TO: - /* - foreach ($list as $set) { - $data[$set->$foreignKey] = $set; - }*/ + $list = []; + $modelName = strtolower(basename(str_replace('\\', '/', $model))); + $currName = strtolower($this->name); + foreach ($resultSet as &$result) { + // 重新组装模型数据 + foreach ($result->toarray() as $key => $val) { + if (strpos($key, '__')) { + list($name, $attr) = explode('__', $key); + $list[$name][$attr] = $val; + unset($result->$key); + } + } + + // 当前模型属性设置 + if (isset($list[$currName])) { + foreach ($list[$currName] as $name => $val) { + $result->__set($name, $val); + } + } + + if (isset($list[$modelName])) { + // 设置关联模型属性 + $result->__set($relation, new $model($list[$modelName])); + } + } break; case self::HAS_MANY: case self::BELONGS_TO_MANY: + $range = []; + $data = []; + + foreach ($resultSet as $result) { + // 获取关联外键列表 + $range[] = $result->$localKey; + } + + // 预载入关联查询 + if (isset($subRelation)) { + // 嵌套预载入 + $list = $model::where($foreignKey, 'in', $range)->with($subRelation)->select(); + } else { + $list = $model::where($foreignKey, 'in', $range)->select(); + } + + // 组装模型数据 foreach ($list as $set) { $data[$set->$foreignKey][] = $set; } + + // 关联数据封装 + foreach ($resultSet as &$result) { + if (isset($data[$result->$localKey])) { + $result->__set($relation, $data[$result->$localKey]); + } + } break; } - // 关联数据封装 - foreach ($resultSet as &$result) { - if (isset($data[$result->$localKey])) { - $result->$relation = $data[$result->$localKey]; - } - } $this->relation = []; } return $resultSet; diff --git a/library/think/db/Driver.php b/library/think/db/Driver.php index bf2ef22a..658a7d48 100644 --- a/library/think/db/Driver.php +++ b/library/think/db/Driver.php @@ -2057,19 +2057,25 @@ abstract class Driver protected function parsePkWhere($data) { $pk = $this->getTableInfo('', 'pk'); + // 获取当前数据表 + if (!empty($this->options['alias'])) { + $alias = $this->options['alias']; + } if (is_string($pk)) { + $key = isset($alias) ? $alias . '.' . $pk : $pk; // 根据主键查询 if (is_array($data)) { - $where[$pk] = isset($data[$pk]) ? $data[$pk] : ['in', $data]; + $where[$key] = isset($data[$pk]) ? $data[$pk] : ['in', $data]; } else { - $where[$pk] = strpos($data, ',') ? ['IN', $data] : $data; + $where[$key] = strpos($data, ',') ? ['IN', $data] : $data; } $this->options['where']['AND'] = $where; } elseif (is_array($pk) && is_array($data) && !empty($data)) { // 根据复合主键查询 foreach ($pk as $key) { if (isset($data[$key])) { - $where[$key] = $data[$key]; + $attr = isset($alias) ? $alias . '.' . $key : $key; + $where[$attr] = $data[$key]; } else { throw new Exception('miss complex primary data'); }