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!
Всё в порядке. Код пристроен, работа завершена.
Ссылки
===================
- Cобственно мануал по Query Builder
Посты по теме:
RSS-подписка
Кохановская 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 с блекджеком и шлюшками, не переписывая всю логику класса.