Все разработчики, рано или поздно, начинают понимать что стандартными средствами ORM библиотеки невозможно реализовать сложные и удобные запросы.
То тут, мы не знаем как написать простейших запрос для подсчёта суммы, без вынимания всех значений, то там, мы не можем составить нетривиальное условие.
В большинстве случаев, кроме удобного доступа к данным, ORM библиотеки доставляют нам головную боль с составлением сложных запросов и огромное количество избыточных выборок.
Сегодня я хочу рассказать, как мы можем обойти часть сложностей и упростить себе работу и, возможно, снизить нагрузку на сервер, используя ORM Jelly.
Выбираем только нужные нам поля
Для указания какие поля нам нужно возратить в кортеже, можно использовать функцию select()
Например:
``
// Простая выборка только нужных полей
Jelly::select(‘user’)
->select(‘id’,‘name’)
-execute();
// Выбираем все поля
Jelly::select(‘user’)
->select(’*‘)
-execute();
// Суммируем значения по колонке
Jelly::select(‘transactions’)
->select(‘title’, DB::expr(“SUM(‘money’) AS money”))
-execute();
// Выбираем все колонки из одной таблицы, и избранные из другой
Jelly::select(‘user’)
->select(DB::expr(’users
.*‘), DB::expr(”providers
.id
AS provider_id”))
-execute();
``
Тут важно помнить, что если какие-то из полей в кортеже у нас не были описаны в модели, то и доступ к ним мы получить привычным способом не сможем.
Для этого нам нужно использовать функцию get('field')
Как-то так:
`
// Суммируем значения по колонке
$transactions = Jelly::select(‘transactions’)
->select(‘title’, DB::expr(“SUM(‘money’) AS money”))
->execute();
// Выводим сумму
foreach ($transactions as $transaction) {
echo $transaction->title . “ ” . $transactions->get(‘money’);
}
`
То что нужно знать
Конечно же, вы должны уже знать как можно группировать условия логически и умеете пользоваться операторами JOIN и WITH (про них описано в официальной справке, если что).
Например вот этот поток сознания вам поможет сориентироваться в обстановке
</p>
<pre lang="php">
$builder = Jelly::select('users')
->join('provider', 'left')
->on('provider.user_id', '=', 'user.id')
->on('provider.name', 'LIKE', 'NBN%')
->where('date_reg', '>', '2010-01-01')
->and_where('active', '=', 1)
->or_where_open()
->where('admin', '=', 1)
->or_where_close()
->execute();
</pre>
<p>
До того как вы вызовете execute()
или load()
вы всегда можете посмотреть что у нас получается в билдере запросов. Для этого его можно просто вывести на печать.
`
$builder = Jelly::select(‘users’)
->where(‘date_reg’, ‘>’, ‘2010-01-01’);
// Выводим получившийся запрос
print $builder;
$users = $builder->execute();
`
Так же, важно знать что код обёрнутый DB::expr('code')
не обрабатывается билдером. Что позволяет нам транслировать в него прямые куски SQL кода.
Подзапросы
Теперь можно попробовать составить что-то необычное, например подзапросы. Внимание, лучше сесть :)
`</p>
<pre lang="php">
$subquery = Jelly::select('price')
->select(DB::expr('SUM(price.spec) AS
spec'))
->where('providers.id', '=', DB::expr('
price.
provider_id'))
->and_where('price.group_id', '=', DB::expr('
groups.
group_id`‘));
$builder = Jelly::select(‘user’)
->select(’provider
.*‘, DB::expr(‘(’.$subquery . ‘) AS spec
’))
->distinct(TRUE)
->order_by(‘spec’, ‘DESC’)
->execute();
``
Этот код не обладает красотой и теми плюшечками ORM которые нам предоставлены из коробки, но именно этот код позволяет писать гибкие запросы.