Yii2 выборка с помощью findOne() и find(). Как выбрать одну записи из БД.
  • 60

Yii2 выборка с помощью findOne() и find(). Как выбрать одну записи из БД.

Автор: admin | 23 октября (Ср.) 2019г. в 18ч.44м.

Как пользоваться find() и findOne() в yii2 Active Record.

В Active Record Yii2 имеется два метода, которые позволяют сделать выборку одного поля из базы данных - findOne() и find() . Пример достижения одного результата, используя эти методы:
// find a single customer whose primary key value is 10
$customer = Customer::findOne(10);

// the above code is equivalent to:
$customer = Customer::find()->where(['id' => 10])->one();

// find the customers whose primary key value is 10, 11 or 12.
$customers = Customer::findOne([10, 11, 12]);

// the above code is equivalent to:
$customers = Customer::find()->where(['id' => [10, 11, 12]])->one();

// find the first customer whose age is 30 and whose status is 1
$customer = Customer::findOne(['age' => 30, 'status' => 1]);

// the above code is equivalent to:
$customer = Customer::find()->where(['age' => 30, 'status' => 1])->one();​
Метод find() с условием where делает то же, что и findOne($condition) , с тем лишь различием, что во втором варианте нужно писать меньше кода.

Таким образом, если нужно выбрать одну запись из базы данных, используя только условие в where, то для этого можно обойтись с помощью findOne($condition). А для более сложной выборки используем find().

Как "работает" findOne().

Для лучшего понимания того, как работает findOne() и чем он отличается от выборки с find()->where([])->one() заглянем в исходники yii2 и рассмотрим, как данный метод реализован. Заглянем в BaseActiveRecord.php:
   /**
     * {@inheritdoc}
     * @return static|null ActiveRecord instance matching the condition, or `null` if nothing matches.
     */
    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])) {
                // if condition is scalar, search for a single primary key, if it is array, search for multiple primary key values
                $condition = [$primaryKey[0] => is_array($condition) ? array_values($condition) : $condition];
            } else {
                throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.');
            }
        }

        return $query->andWhere($condition);
    }​

Из исходников видно, что findOne() собирается на основе find()->andWhere($condition)->one(); и теперь картина становится яснее.

Соответственно, в findOne() можно передавать так же как и в where параметры в 3х вариантах:

  • строковый формат, Например, 'status=1'
  • формат массива, Например, ['status' => 1, 'type' => 2]
  • формат операторов, Например, ['like', 'name', 'test']
Еще приведу примеры:
// ...WHERE (`status` = 10) AND (`type` IS NULL) AND (`id` IN (4, 8, 15))
Article::findOne([
    'status' => 10,
    'type' => null,
    'id' => [4, 8, 15],
]);

//Or equivalent
Article::find()->where([
    'status' => 10,
    'type' => null,
    'id' => [4, 8, 15],
])->one();​

//////////////////////

Article::findOne(['between', 'id', 1, 10]);

//Or equivalent
Article::find()->where(['between', 'id', 1, 10])->one();​

Метод возвращает первое найденное поле. И даже, если под условие попадает несколько результатов - вернется только первый найденный.

Для возврата всех результатов выборки используется метод Class::findAll($condition) и аналогичная конструкция в более грамоздком виде Class::find()->where()->all() ;

Читайте также из этой серии:

Приветствую!

Меня зовут Сергей. Я - автор этого блога.

Если Вам был полезен материал на моем сайте, поддержите пожалуйста мой проект, чтобы о нем узнали другие люди - кликните plizz :) на иконку в соц. сети, чтобы поделиться материалом с другими.