首先看findOne的函数定义,该函数定义在BaseActiveRecord当中
return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
public static function findOne($condition)
{
return static::findByCondition($condition)->one();
}
protected static function findByCondition($condition)
{
$query = static::find();
if (!ArrayHelper::isAssociative($condition)) {
// query by primary key
$primaryKey = static::primaryKey();
if (isset($primaryKey[0])) {
$condition = [$primaryKey[0] => $condition];
} else {
throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.');
}
}
return $query->andWhere($condition);
}
public static function find()
{
return Yii::createObject(ActiveQuery::className(), [get_called_class()]);
}
public function andWhere($condition, $params = [])
{
if ($this->where === null) {
$this->where = $condition;
} else {
$this->where = ['and', $this->where, $condition];
}
$this->addParams($params);
return $this;
}
public function one($db = null)
{
$row = parent::one($db);
if ($row !== false) {
$models = $this->populate([$row]);
return reset($models) ?: null;
} else {
return null;
}
}
public function one($db = null)
{
return $this->createCommand($db)->queryOne();
}
public function createCommand($db = null)
{
if ($db === null) {
$db = Yii::$app->getDb();
}
list ($sql, $params) = $db->getQueryBuilder()->build($this);
return $db->createCommand($sql, $params);
}
public function build($query, $params = [])
{
$query = $query->prepare($this);
$params = empty($params) ? $query->params : array_merge($params, $query->params);
$clauses = [
$this->buildSelect($query->select, $params, $query->distinct, $query->selectOption),
$this->buildFrom($query->from, $params),
$this->buildJoin($query->join, $params),
$this->buildWhere($query->where, $params),
$this->buildGroupBy($query->groupBy),
$this->buildHaving($query->having, $params),
];
$sql = implode($this->separator, array_filter($clauses));
$sql = $this->buildOrderByAndLimit($sql, $query->orderBy, $query->limit, $query->offset);
if (!empty($query->orderBy)) {
foreach ($query->orderBy as $expression) {
if ($expression instanceof Expression) {
$params = array_merge($params, $expression->params);
}
}
}
if (!empty($query->groupBy)) {
foreach ($query->groupBy as $expression) {
if ($expression instanceof Expression) {
$params = array_merge($params, $expression->params);
}
}
}
$union = $this->buildUnion($query->union, $params);
if ($union !== '') {
$sql = "($sql){$this->separator}$union";
}
return [$sql, $params];
}
return $db->createCommand($sql, $params);
public function createCommand($sql = null, $params = [])
{
/** @var Command $command */
$command = new $this->commandClass([
'db' => $this,
'sql' => $sql,
]);
return $command->bindValues($params);
}
public function bindValues($values)
{
if (empty($values)) {
return $this;
}
$schema = $this->db->getSchema();
foreach ($values as $name => $value) {
if (is_array($value)) {
$this->_pendingParams[$name] = $value;
$this->params[$name] = $value[0];
} else {
$type = $schema->getPdoType($value);
$this->_pendingParams[$name] = [$value, $type];
$this->params[$name] = $value;
}
}
return $this;
}
public function queryOne($fetchMode = null)
{
return $this->queryInternal('fetch', $fetchMode);
}
protected function queryInternal($method, $fetchMode = null)
{
$rawSql = $this->getRawSql();
Yii::info($rawSql, 'yii\db\Command::query');
if ($method !== '') {
$info = $this->db->getQueryCacheInfo($this->queryCacheDuration, $this->queryCacheDependency);
if (is_array($info)) {
/* @var $cache \yii\caching\Cache */
$cache = $info[0];
$cacheKey = [
__CLASS__,
$method,
$fetchMode,
$this->db->dsn,
$this->db->username,
$rawSql,
];
$result = $cache->get($cacheKey);
if (is_array($result) && isset($result[0])) {
Yii::trace('Query result served from cache', 'yii\db\Command::query');
return $result[0];
}
}
}
$this->prepare(true);
$token = $rawSql;
try {
Yii::beginProfile($token, 'yii\db\Command::query');
$this->pdoStatement->execute();
if ($method === '') {
$result = new DataReader($this);
} else {
if ($fetchMode === null) {
$fetchMode = $this->fetchMode;
}
$result = call_user_func_array([$this->pdoStatement, $method], (array) $fetchMode);
$this->pdoStatement->closeCursor();
}
Yii::endProfile($token, 'yii\db\Command::query');
} catch (\Exception $e) {
Yii::endProfile($token, 'yii\db\Command::query');
throw $this->db->getSchema()->convertException($e, $rawSql);
}
if (isset($cache, $cacheKey, $info)) {
$cache->set($cacheKey, [$result], $info[1], $info[2]);
Yii::trace('Saved query result in cache', 'yii\db\Command::query');
}
return $result;
}