Kohana. Query Builder. Правила хорошего тона.



kohana C базами данных в Kohana принято работать через ORM. Но не секрет, что ORM не покрывает всех нужд и потребностей. В таких случаях нужно что-то другое.

Для самых нетерпеливых – прямые запросы к БД. Метод простой и эффективный. Только ваши запросы и ничего больше. Минусы этого метода в том, что составляя запрос вы сами несёте ответственность за возможную инъекцию. Работать можно, но нужно тщательно проверять все поступающие данные.

Query Builder
===================
Это нечто среднее между вышеописаными методами. О нём я и хочу поговорить в этом посте.

Я не ставлю себе задачу переписать сюда мануал, хочу просто показать принцип Query Builder. Вот простой пример использования

1
2
3
4
5
6
7
 $query_result= DB::select('a.id','a.b_id')
                    ->distinct(true)
                    ->from('a')
                    ->join('bs')->on('a.b_id', '=', 'bs.id')
                    ->where('a.something','=','1')
                    ->group_by("a.b_id")
                    ->execute();

Тут, в отличие от ORM, можно наворотить запрос произвольной сложности. Например, часто приходится слышать, а как сделать DISTINCT? Или как выбрать только пару полей из выборки? Для всего этого и есть Query Builder.

Модель
===================
Считается хорошим тоном включать все мало-мальски сложные и хитрые функции работы с базами данных в модель. И это правильно. Как это сделать? Очень просто. Берём составленных выше запрос и помещаем в модель.

Кстати, раз уж делаем модель по таблице – наверняка будем использовать ORM. Так что пусть модель будет ORM.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
Class Model_A extends ORM {
....................
public function myfunc(){
        return  DB::select('as.id','as.b_id')
             ->distinct(true)
             ->from($this->_table_name)
             ->join('bs')->on('as.b_id', '=', 'bs.id')
             ->where('a.something','=','1')
             ->group_by("as.b_id")
             ->execute();
}
};
?>

Вызов функции прост

1
2
3
4
5
$myresult= ORM::factory('a')->myfunc();
foreach($myresult as $a)
{
    echo $a['id'];
}

Обратите внимание, что возвращаемые объекты не ORM!

Всё в порядке. Код пристроен, работа завершена.
Ссылки
===================

Посты по теме:

  1. Kohana для чайников. Простейший ORM
  2. Kohana. Ускоряем ORM
  3. Kohana для чайников. Настраиваем базу данных
  4. Kohana 3.0. Шпаргалка по ORM
  5. Kohana для чайников. Файловая структура, или история одной ошибки.

Категории Kohana |
автор: altesack / Воскресенье, Апрель 24, 2011 / 1 коммент »

Один коммент

    Кохановская ORM умеет транслировать запросы к DB без посторонней помощи. Т.е. можно написать

    $data = ORM::factory(’a')->distinct(true)
    ->join(’bs’)->on(’as.b_id’, ‘=’, ‘bs.id’)
    ->where(’a.something’,'=’,'1′)
    ->group_by(”as.b_id”)
    ->find_all();

    Разумеется, этот вызов можно и нужно инкапсулировать в модель. При этом $data будет экземпляром Database_MySQL_Result (или другого потомка Database_Result, зависит от используемого драйвера), но $data->current() будет возвращать экземпляр класса Model_A – можно ходить по выборке foreach’ем, рассчитывая каждый раз получать экземпляр своего класса.

    С одной стороны, такая архитектура выглядит довольно удобной, с другой – выборку очень неудобно кешировать. Лучший вариант – класс-коллекция, содержащий внутри себя всю выборку, что снимет эту проблему. Плюс Коханы в том, что можно переопределить несколько методов в классе ORM и получить свой ORM с блекджеком и шлюшками, не переписывая всю логику класса.