Абстрактный доступ к БД с помощью ADODB
Maxim Matyukhin
Подробное описание абстрактного класса баз данных ADODB. Установка, примеры использования, особенности, ADODB & PEAR.
1. Пару слов об ADODB
2. Установка 3. Простые примеры 4. Практическое использование 4.1 Постраничный вывод и ограничение SELECT-запросов 5. ADODB & PEAR4.2 Генерирование INSERT/UPDATE запросов 4.3 Работа с транзакциями 4.4 Последовательности 4.5 Кеширование запросов 4.6 Статистика запросов 6. Заключение 1. Пару слов об ADODBДля начала, скажу что статья рассчитана на программистов, имеющих опыт работы с СУБД, а не на начинающих пхпешников. Я предполагаю, что вы знакомы с PHP, ОПП, SQL и имеете опыт разработки web-приложений. ADODB - это абстрактный класс доступа к базам данных, написанный на PHP. Для тех, кто в танке поясню на примере. Предположим вы написали скрипт под mysql. И тут заказчик говорит Вам, что хостинг меняется и там есть только PostgreSQL. Если вы не использовали класс абстрактного доступа к базам данных, то вам пришлось бы:
Если бы вы использовали абстрактный слой доступа к БД, то вам скорее всего не пришлось бы менять php-код (только в одном месте указали бы что используете postgresql) и изменить SQL-запросы (хотя иногда и это не понадобилось бы). Я намеренно в этом описании использовал фразу "абстрактный класс доступа к БД", поскольку ADODB - не единственный подобный класс. Наиболее известные конкуренты:
Насколько я знаю, другие классы имеют слабую функциональность, хотя должен признать, работают быстрее. Многие пишут такие классы сами, но я не сторонник изобретения велосипедов. Противники таких массивных классов, как ADODB или Pear::DB утверждают, что их использование плохо сказывается на производительнеости. Да, производительность падает и это вполне логично. НО:
От себя могу добавить, что многие из написанных мною сайтов используют ADODB и проблем с производительностью не имеют. 2. УстановкаЗдесь все просто. Скачайте с http://php.weblogs.com/adodb архив и распакуйте его (например в папку ./adodb). Все, класс готов к использованию. Можете еще скачать и php-extension, но я его использовать не пробовал. Чтобы использовать класс, вам необходимо включить (include) файл ./adodb/adodb.inc.php 3. Простые примерыПример 1 // указываем тип БД Данный пример демонстрирует подключение к БД. В строке
Создается объект соединения с базой данных. Именно через поля и методы данного объекта и будет в дальнейшем вестись работа с базой данных. Что касается режима отладки, то по умолчанию он выключен. При включенном режиме отладки на экран броузера будут выводиться SQL-запросы и тексты ошибок (если такие были). Очень упрощает процесс написания и отладки скриптов. Метод $conn->setFetchMode() - указывает, каким образом данные о записях будут записаны в массив - будет ли это ассоциативный массив, или простой нумерованный или и тот и другой. Ей нужно установить одно из значений (0, 1, 2, 3). Для пояснений приведу код из исходников adodb:
Судя по исходникам ADODB_FETCH_DEFAULT == ADODB_FETCH_BOTH Теперь сделаем запрос к БД:
Вот простейший пример запроса к БД. Метод $conn->Execute() выполняет запрос к базе данных и возвращает множество записей (recordset). Множество записей (recordset) - в ADODB является отдельным объектом, который имеет свои поля и методы для работы с полученными записями. Некоторые из них использованы в данном примере.
Метод $conn->Execute() - может быть использован для любых запросов: $conn->Execute("DELETE FROM tab WHERE id = ".$id); Опишу еще некоторые полезные методы класса AdoConnection:
4. Практическое использованиеДумаю этот раздел будет наиболее интересен программистам. 4.1 Постраничный вывод и ограничение SELECT-запросовВообще-то не все базы данных умеют делать запросы типа: SELECT * FROM tab LIMIT 0, 10 а все те, которые умеют, делают это по разному:
Класс adodb сам может делать ограниченные выборки, составляя правильные SQL-запросы под указанную БД, поддерживающую лимитированные SELECT-запросы
Метод $conn->SelectLimit() сам построит правильный SQL-запрос. На основе этого метода в ADODB работают функции для постраничной выборки: // получаем найденное количество записей Метод $conn->PageExecute() кроме простого LIMIT-запроса делает автоматически еще и запрос типа: SELECT COUNT(*) FROM tab Таким образом он сам узнает, сколько всего по данному запросу найдено строк. Это количество можно узнать с помощью метода: $res->MaxRecordCount(); Также для управления постраничным выводом есть следующие методы:
4.2 Генерирование INSERT/UPDATE запросовДля начала пример: // массив, который нужно вставить в таблицу // пример генерирования UPDATE-запроса
// получаем данные о строке, которую нужно обновить Так вот идея в том, чтобы все данные, которые нужно вставить записать в ассоциативный массив. Сделать запрос к БД чтобы получить имена полей таблицы и сконструировать SQL-запрос по этим данным. Уверен, что будет много противников этого метода (мол лишний SQL-запрос к БД делвть), но мне эти функции кажутся очень удобными. 4.3 Работа с транзакциямиНу это вообще сказка :). Вот пример из мануала:
Метод $conn->CompleteTrans(); сам проверит, были ли ошибки и если так - сделает откат. ADODB имеет еще и другие функции для работы с транзакциями, но они устарели и разработчики ADODB рекомендуют использовать этот вариант. 4.4 ПоследовательностиЧасто при работе с таблицами каждой записи нужно присвоить уникальный идентификатор, который потом используется в качестве первичного ключа. Но не все СУБД поддерживают такую возможность. ADODB эмулирует эту возможность почти для всех СУБД. На практике это выглядит примерно так:
Метод $conn->GenID() создает последовательность site_users (если она до этого не была создана) и возвращает значение на единицу больше чем текущее значение последовательности. 4.5 Кеширование запросовADODB поддерживает серверное кеширование запросов. Суть в том, что при первом выполнении запроса его результаты заносятся в кеш-файл. При последующем таком же запросе (если кеш-файл не устарел) данные будут браться из файла. Честно говоря, мне не нравится метод, которым они производят кеширование (по-моему они слишком уж универсальным сделали его) и предпочитаю делать кеширование своими руками. Если вас все-таки интересует кеширование, то работает оно так:
По умолчанию время жизни кеш-файлов - 1 час. Это время можно изменить 2-мя путями: // или так: 4.6 Статистика запросов.Наверное видели на некоторых сайтах выводится статистика:
Как вычисляется время генерирования страницы - к данной статье не относится, а вот посчитать количество запросов к БД (а также посчитать количество запросов, взятых из кеша) ADODB позволяет: function CountCachedExecs($conn, $secs2cache, $sql, $inputarray) { $conn = NewADOConnection('mysql'); ... Данные функции вызываются до запроса, поэтому вы можете с их помощью переписать SQL-запрос. 5. ADODB & PEARЯ являюсь фанатом как adodb так и репозитария PEAR. К сожалению основным классом работы с базами данных в PEAR является PEAR::DB И многие PEAR-классы используют его. Что же делать любителям adodb? Во-первых, если хорошо присмотреться, то классов, использующих PEAR::DB не так уж и много. У меня почти весь pear-репозитарий на компьютере и там pear::DB используют лишь
Во-вторых, многие классы использую "контейнеры", и для этих классов можно написать контейнер, использующий ADODB (как писать контейнеры - смотрите на примере контейнеров pear::DB указанных классов). В-третьих, ADODB имеет файл adodb-pear.inc.php который является эмуляцией класса PEAR::DB и остальные классы можно подогнать под работу с adodb с минимальными телодвижениями (часто достаточно в тексте класса строку require_once('DB.php'); заменить на require_once('adodb-pear.inc.php'); но так бывает не всегда). Так что ADODB можно успешно применять с pear-классами. Приведу пример использования adodb c классом pear::XML::sql2xml. Для тех кто не в курсе - этот класс трансформирует результат запроса (SELECT) к БД в XML-строку: $db = DB::connect("mysql://root@localhost/lot"); Те кто уже имеют опыт работы с XML_sql2xml наверное чаще применяют код, который предлагает автор класса XML_sql2xml:
и
Оба эти примера не сработают и нужно будет править класс XML_sql2xml. 6. ЗаключениеПоскольку статья носит ознакомительный характер, многое осталось "за кадром". Я не пытался описать все классы, поля и методы - для этого есть официальная документация. Также я не описывал функциональные возможности, которые не использовал на практике:
Ссылки по теме
Страница сайта http://silicontaiga.ru
Оригинал находится по адресу http://silicontaiga.ru/home.asp?artId=5943 |