From 880562b42c00cd12d18a5f1aa8f5dfb4d0a26d96 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 12 Apr 2016 08:33:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E9=A2=84=E8=BD=BD=E5=85=A5?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/think/Model.php | 44 ++++++++++++++++++++++++++++++++----- library/think/db/Driver.php | 42 +++++++++++++++++++++-------------- 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/library/think/Model.php b/library/think/Model.php index 632d406a..d3459365 100644 --- a/library/think/Model.php +++ b/library/think/Model.php @@ -612,10 +612,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess * 查找单条记录 * @access public * @param mixed $data 主键值或者查询条件(闭包) + * @param string $with 关联预查询 * @param bool $cache 是否缓存 * @return mixed */ - public static function get($data = '', $cache = false) + public static function get($data = '', $with = '', $cache = false) { $db = self::db(); if ($data instanceof \Closure) { @@ -633,7 +634,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } } - $result = $db->find($data); + $result = self::with($with)->find($data); if ($cache && $result instanceof Model) { // 缓存模型数据 @@ -656,7 +657,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess call_user_func_array($data, [ & $db]); $data = []; } - return $db->with($with)->select($data); + return self::with($with)->select($data); } /** @@ -739,6 +740,35 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return $this; } + public static function with($with = '') + { + if (is_string($with)) { + $with = explode(',', $with); + } + $db = self::db(); + if (empty($with)) { + return $db; + } + $class = new static(); + $joinName = basename(str_replace('\\', '/', static::class)); + $joinTable = Db::name($joinName)->getTableName(); + $db->table($joinTable)->alias($joinName)->field(true, false, $joinTable, $joinName); + foreach ($with as $name) { + $model = $class->$name(); + list($type, $foreignKey, $localKey) = $class->relation; + 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); + } + } + return $db->with($with); + + } + /** * 预载入关联查询 返回数据集 * @access public @@ -748,7 +778,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ public function eagerly($resultSet, $relation) { - $relations = explode(',', $relation); + + $relations = is_string($relation) ? explode(',', $relation) : $relation; foreach ($relations as $relation) { $range = []; @@ -772,9 +803,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess switch ($type) { case self::HAS_ONE: case self::BELONGS_TO: + /* foreach ($list as $set) { - $data[$set->$foreignKey] = $set; - } + $data[$set->$foreignKey] = $set; + }*/ break; case self::HAS_MANY: case self::BELONGS_TO_MANY: diff --git a/library/think/db/Driver.php b/library/think/db/Driver.php index 86c7601a..bf2ef22a 100644 --- a/library/think/db/Driver.php +++ b/library/think/db/Driver.php @@ -624,26 +624,42 @@ abstract class Driver } /** - * 指定查询字段 支持字段排除 + * 指定查询字段 支持字段排除和指定数据表 * @access public * @param mixed $field * @param boolean $except 是否排除 + * @param string $tableName 数据表名 + * @param string $prefix 字段前缀 * @return Model */ - public function field($field, $except = false) + public function field($field, $except = false, $tableName = '', $prefix = '') { + if (is_string($field)) { + $field = explode(',', $field); + } if (true === $field) { // 获取全部字段 - $fields = $this->getTableInfo('', 'fields'); + $fields = $this->getTableInfo($tableName, 'fields'); $field = $fields ?: '*'; } elseif ($except) { // 字段排除 - if (is_string($field)) { - $field = explode(',', $field); - } - $fields = $this->getTableInfo('', 'fields'); + $fields = $this->getTableInfo($tableName, 'fields'); $field = $fields ? array_diff($fields, $field) : $field; } + if ($tableName) { + // 添加统一的前缀 + $prefix = $prefix ?: $tableName; + foreach ($field as $key => $val) { + if (is_numeric($key)) { + $val = $prefix . '.' . $val . ' AS ' . $prefix . '__' . $val; + } + $field[$key] = $val; + } + } + + if (isset($this->options['field'])) { + $field = array_merge($this->options['field'], $field); + } $this->options['field'] = $field; return $this; } @@ -1450,10 +1466,9 @@ abstract class Driver */ protected function parseField($fields) { - if (is_string($fields) && strpos($fields, ',')) { - $fields = explode(',', $fields); - } - if (is_array($fields)) { + if ('*' == $fields || empty($fields)) { + $fieldsStr = '*'; + } elseif (is_array($fields)) { // 支持 'field1'=>'field2' 这样的字段别名定义 $array = []; foreach ($fields as $key => $field) { @@ -1464,12 +1479,7 @@ abstract class Driver } } $fieldsStr = implode(',', $array); - } elseif (is_string($fields) && !empty($fields)) { - $fieldsStr = $this->parseKey($fields); - } else { - $fieldsStr = '*'; } - //TODO 如果是查询全部字段,并且是join的方式,那么就把要查的表加个别名,以免字段被覆盖 return $fieldsStr; }