This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
khosb/includes/kohana/modules/userguide/guide/ru-ru/tutorials.databases.md
2011-05-03 09:49:01 +10:00

15 KiB
Raw Blame History

Базы данных

Kohana 3.0 поставляется с надежным модулем для работы с базами данных. По умолчанию модуль БД содержит драйверы для MySQL и PDO.

Модуль Database содержится в дистрибутиве Kohana 3.0, но требует подключение перед использованием. В файле application/bootstrap.php измените вызов метода [Kohana::modules], подключив модуль Database:

Kohana::modules(array(
    ...
    'database' => MODPATH.'database',
    ...
));

Настройка

После подключения модуля необходимо создать файл настроек, чтобы модуль знал как соединиться с базой данных. Пример конфигурационного файла можно найти в modules/database/config/database.php.

Структура группы настроек базы данных ("instance") выглядит следующим образом:

string INSTANCE_NAME => array(
    'type'         => string DATABASE_TYPE,
    'connection'   => array CONNECTION_ARRAY,
    'table_prefix' => string TABLE_PREFIX,
    'charset'      => string CHARACTER_SET,
    'profiling'    => boolean QUERY_PROFILING,
),

[!!] В одном конфигурационном файле можно определить несколько таких групп.

Очень важно понимать каждый параметр конфигурации.

INSTANCE_NAME
Соединения могут быть названы как Вы захотите, но одно из них обязательно должно называться "default" (группа по умолчанию).
DATABASE_TYPE
Один из установленных драйверов баз данных. Kohana поставляется с драйверами "mysql" и "pdo".
CONNECTION_ARRAY
Специфические настройки драйвера для соединения с БД. (Настройки драйвера описаны ниже.)
TABLE_PREFIX
Префикс, который будет добавлен к названиям таблиц классом query builder.
QUERY_PROFILING
Включает профилирование запросов к БД.

Пример

Ниже описаны два соединения с MySQL, одно локальное, а другое удаленное.

return array
(
    'default' => array
    (
        'type'       => 'mysql',
        'connection' => array(
            'hostname'   => 'localhost',
            'username'   => 'dbuser',
            'password'   => 'mypassword',
            'persistent' => FALSE,
            'database'   => 'my_db_name',
        ),
        'table_prefix' => '',
        'charset'      => 'utf8',
        'profiling'    => TRUE,
    ),
    'remote' => array(
        'type'       => 'mysql',
        'connection' => array(
            'hostname'   => '55.55.55.55',
            'username'   => 'remote_user',
            'password'   => 'mypassword',
            'persistent' => FALSE,
            'database'   => 'my_remote_db_name',
        ),
        'table_prefix' => '',
        'charset'      => 'utf8',
        'profiling'    => TRUE,
    ),
);

Настройки соединения

Каждый драйвер БД имеет свои настройки соединения.

MySQL

БД MySQL поддерживает следующие параметры массива connection:

Тип Параметр Описание Значение по умолчанию
string hostname Имя сервера или IP-адрес localhost
integer port Номер порта NULL
string socket сокет UNIX NULL
string username Имя пользователя NULL
string password Пароль NULL
boolean persistent Постоянное соединение FALSE
string database Имя базы данных (схемы) kohana

PDO

База данных PDO database принимает следующие опции массива connection:

Тип Параметр Описание Значение по умолчанию
string dsn Идентификатор источника PDO localhost
string username Имя пользователя NULL
string password Пароль NULL
boolean persistent Постоянное соединение FALSE

!! Если Вы используете PDO и не уверены, что прописывать в параметре dsn, ознакомьтесь с PDO::__construct.

Соединения и сущности

Каждая группа настроек связана с экземпляром базы данных ("сущность"). Каждая сущность может быть получена через вызов [Database::instance]:

$default = Database::instance();
$remote  = Database::instance('remote');

Чтобы порвать соединение с базой данных, просто уничтожьте объект:

unset($default, Database::$instances['default']);

Если Вы хотите разорвать соединения со всеми сущностями за раз:

Database::$instances = array();

Создаем запросы

Существует два способа создать запросы. Простейший путь - использование [Database_Query] для создания запросов, через [DB::query]. Эти запросы называются "подготовленные выражения" и позволяют устанавливать параметры, которые автоматически экранируются. Второй путь - построение через специальные методы. Это возможно с помощью объекта query builder.

[!!] Все запросы выполняются методом execute, который принимает объект [Database] или имя сущности. Смотри [Database_Query::execute].

Подготовленные выражения

Подготовленные выражения позволяют писать SQL-запросы вручную, в то же время значения будут автоматически экранированы, чтобы избежать SQL-инъекций. Создать запрос просто:

$query = DB::query(Database::SELECT, 'SELECT * FROM users WHERE username = :user');

Фабричный метод [DB::query] создает новый класс [Database_Query] и возвращает его, поддерживая цепочки вызовов. Запрос содержит параметр :user, которому будет назначено значение:

$query->param(':user', 'john');

[!!] Имя параметра может быть любой строкой, в дальнейшем оно будет заменено функцией strtr. Рекомендуется не использовать знак доллара в составе имени параметра во избежание путаницы.

Если Вы хотите увидеть SQL, предназначенный для выполнения, просто преобразуйте объект в строку:

echo Kohana::debug((string) $query);
// выведет:
// SELECT * FROM users WHERE username = 'john'

Также Вы можете изменить параметр :user, снова вызвав [Database_Query::param]:

$query->param(':user', $_GET['search']);

[!!] Для задания нескольких параметров за раз используйте [Database_Query::parameters].

После установки всех параметров можно выполнить запрос:

$query->execute();

Также допустимо привязать параметр к переменной, используя ссылки на переменные. Это может стать очень полезным при многократном выполнении схожих запросов:

$query = DB::query(Database::INSERT, 'INSERT INTO users (username, password) VALUES (:user, :pass)')
    ->bind(':user', $username)
    ->bind(':pass', $password);

foreach ($new_users as $username => $password)
{
    $query->execute();
}

В данном примере переменные $username и $password меняются в каждой итерации цикла foreach. Когда переменные меняются, также изменяют значение и параметры запроса :user и :pass. Правильное и уместное использование привязки параметров может сделать код более компактным.

Конструктор запросов

Динамическое создание запросов с использованием объектов и методов позволяет писать запросы очень быстро и предсказуемо. Построитель запросов также заключает в кавычки идентификаторы (имена таблиц и полей), также как и экранирует значения.

[!!] На данный момент невозможно комбинировать построитель запросов с подготовленными выражениями.

Выборка (SELECT)

Каждый тип запросов представлен отдельным классом со своими методами. К примеру, чтобы создать запрос типа SELECT, используем [DB::select]:

$query = DB::select()->from('users')->where('username', '=', 'john');

По умолчанию, [DB::select] будет запрашивать все поля (SELECT * ...), но можно указать, какие столбцы извлекать:

$query = DB::select('username', 'password')->from('users')->where('username', '=', 'john');

А теперь посмотрим, к чему привела эта цепочка вызовов. Сперва мы создаем новый объект выборки методом [DB::select]. Далее, устанавливаем таблицу(ы) с помощью метода from. И напоследок, ищем конкретные записи через метод where. Можно посмотреть генерируемый код SQL просто преобразовывая объект к строке:

echo Kohana::debug((string) $query);
// Покажет:
// SELECT `username`, `password` FROM `users` WHERE `username` = 'john'

Обратили внимание, что имена полей и таблиц автоматически экранированы, также как и значения? Это одно из ключевых преимуществ использования построителя запросов.

Также допустимо создавать псевдонимы AS для выборки:

$query = DB::select(array('username', 'u'), array('password', 'p'))->from('users');

Сгенерируется следующий SQL-запрос:

SELECT `username` AS `u`, `password` AS `p` FROM `users`

Вставка (INSERT)

Чтобы создать записи в базе данных, используйте [DB::insert], создающий запросы INSERT:

$query = DB::insert('users', array('username', 'password'))->values(array('fred', 'p@5sW0Rd'));

Запрос сформирует код:

INSERT INTO `users` (`username`, `password`) VALUES ('fred', 'p@5sW0Rd')

Обновление (UPDATE)

Для редактирования существующей записи предназначен метод [DB::update], он возвращает запрос UPDATE:

$query = DB::update('users')->set(array('username' => 'jane'))->where('username', '=', 'john');

В результате получим запрос:

UPDATE `users` SET `username` = 'jane' WHERE `username` = 'john'

Удаление (DELETE)

Для удаления записи используется [DB::delete], он создает запрос DELETE:

$query = DB::delete('users')->where('username', 'IN', array('john', 'jane'));

Получим следующий запрос:

DELETE FROM `users` WHERE `username` IN ('john', 'jane')

Функции работы с базами данных

Иногда Вы можете столкнуться с ситуацией, когда надо вызвать COUNT или другую функцию СУБД внутри запроса. Построитель запросов позволяет использовать эти функции двумя способами. Первый - применение кавычек внутри псевдонимов:

$query = DB::select(array('COUNT("username")', 'total_users'))->from('users');

Это выглядит почти также, как и стандартные псевдонимы, но имя поля обрамлено двойными кавычками. Каждый раз, когда значение в двойных кавычках обнаруживается внутри имени столбца, только часть внутри этих кавычек будет экранирована. Сгенерируется код SQL:

SELECT COUNT(`username`) AS `total_users` FROM `users`

Сложные выражения

"Закавыченные" псевдонимы могут решить многие проблемы, но время от времени может понадобиться сложное выражение. В таких случаях надо использовать выражения, создаваемые методом [DB::expr]. Выражение используется для прямого вывода, экранирование не происходит.