/** * 获取关联模型的字段 并解决混淆 * @access protected * @param \think\db\Query $query 查询对象 * @param string $name 模型名称 * @param string $table 关联表名称 * @param array $map 字段映射 * @param array $fields 查询字段 * @return array */ protected static function getModelField($query, $name, $table = '', $map = [], $fields = []) { // 获取模型的字段信息 $fields = $fields ?: $query->getTableInfo($table, 'fields'); $array = []; foreach ($fields as $field) { if ($key = array_search($name . '.' . $field, $map)) { // 需要处理映射字段 $array[] = $name . '.' . $field . ' AS ' . $key; } else { $array[] = $field; } } return $array; }
/** * 附加查询表达式 * @access protected * @param \think\db\Query $query 查询对象 * @return \think\db\Query */ protected static function attachQuery($query) { $master = basename(str_replace('\\', '/', get_called_class())); $class = new static(); $fields = self::getModelField($master, '', $class->mapFields); $query->alias($master)->field($fields); foreach (static::$relationModel as $key => $model) { $name = is_int($key) ? $model : $key; $table = is_int($key) ? self::db()->name($name)->getTable() : $model; $query->join($table . ' ' . $name, $name . '.' . $class->fk . '=' . $master . '.' . $class->getPk()); $fields = self::getModelField($name, $table, $class->mapFields); $query->field($fields); } return $query; }
protected function parseClosure($call, $show = true) { $query = new Query($this->connection); call_user_func_array($call, [&$query]); return $query->buildSql($show); }
/** * 查找单条记录 * @access public * @param array|string|Query|\Closure $data * @return array|false|\PDOStatement|string|Model * @throws DbException * @throws ModelNotFoundException * @throws DataNotFoundException */ public function find($data = null) { if ($data instanceof Query) { return $data->find(); } elseif ($data instanceof \Closure) { call_user_func_array($data, [&$this]); $data = null; } // 分析查询表达式 $options = $this->parseExpress(); if (!is_null($data)) { // AR模式分析主键条件 $this->parsePkWhere($data, $options); } $options['limit'] = 1; $result = false; if (empty($options['fetch_sql']) && !empty($options['cache'])) { // 判断查询缓存 $cache = $options['cache']; if (true === $cache['key'] && !is_null($data) && !is_array($data)) { $key = 'think:' . $options['table'] . '|' . $data; } else { $key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options)); } $result = Cache::get($key); } if (!$result) { // 生成查询SQL $sql = $this->builder()->select($options); // 获取参数绑定 $bind = $this->getBind(); if ($options['fetch_sql']) { // 获取实际执行的SQL语句 return $this->connection->getRealSql($sql, $bind); } // 执行查询 $result = $this->query($sql, $bind, $options['master'], $options['fetch_class']); if ($result instanceof \PDOStatement) { // 返回PDOStatement对象 return $result; } if (isset($cache)) { // 缓存数据 if (isset($cache['tag'])) { Cache::tag($cache['tag'])->set($key, $result, $cache['expire']); } else { Cache::set($key, $result, $cache['expire']); } } } // 数据处理 if (!empty($result[0])) { $data = $result[0]; if (!empty($this->model)) { // 返回模型对象 $model = $this->model; $data = new $model($data); $data->isUpdate(true, isset($options['where']['AND']) ? $options['where']['AND'] : null); if ($this->allowField) { $data->allowField($this->allowField); } // 关联查询 if (!empty($options['relation'])) { $data->relationQuery($options['relation']); } if (!empty($options['with'])) { // 预载入 $data->eagerlyResult($data, $options['with'], is_object($result) ? get_class($result) : ''); } } } elseif (!empty($options['fail'])) { $this->throwNotFound($options); } else { $data = null; } return $data; }
/** * 查询默认不包含软删除数据 * @access protected * @param \think\db\Query $query 查询对象 * @return void */ protected function base($query) { $field = $this->getDeleteTimeField(true); $query->where($field, 'null'); }
/** * 查询默认不包含软删除数据 * @access protected * @param \think\db\Query $query 查询对象 * @return void */ protected static function base($query) { if (static::$deleteTime) { $query->where(static::$deleteTime, 'null'); } }