2. WTF is ORM?
ORM = Объектно-реляционная проекция. Т.е. связка
между реляционной БД и объектно-ориентированным
кодом
3. Сравним RDB и OOP
ООП РСУБД
Объект База данных
Тип название таблицы
Аттрибуты столбцы
Методы :-( нет у нас методов
4. Зачем нужен ORM?
ORM сохраняет объекты в базу и достаёт их. Именно
объекты, а не строки!!!
Без него в нашем коде получается смесь двух
совершенно разных языков - SQL и Perl.
Это тупо неудобно!
my $message = $user->messages->find( $message_id );
my $message = s("SELECT * FROM mess WHERE id=?",undef,$id"):
5. DBIx::Class
Почему именно он?
Самый популярный
Большое количество плагинов
Есть связки с Catalyst и HTML::FormFu
Я це люблю™
6. Импорт структуры базы
DBIx::Class::Schema::Loader
Таблицы => Классы
Столбцы => Аттрибуты
Комментарии к таблицам => POD*
Foreign-ключи => Связи между классами.
* мой патч в последней версии Schema::Loader-а ;-P
7. Basics
В DBIx::Class есть две основные сущности
ResultSet (=where)
Row (=object)
ResultSet - это структура для формирования запроса.
Row - полученная из базы строка.
8.
9. Начинаем работать
Классы:
My::Schema::User
My::Schema::Message
My::Schema::Forum
My::Schema::Reply
Связки превращаются в методы:
$user->messages, $message->replies, $reply->message;
10. Начинаем работать (строки)
my @rows = $rs->all;
$row->id
$row->name
$row->name( 'Изя' )
$row->update
$row->delete
$row->insert
11. Отношения
package My::Schema::User;
__PACKAGE__->add_columns( qw(id name gender) );
__PACKAGE__->has_many( 'posts' => 'My::Schema::Posts', 'user_id' );
__PACKAGE__->belongs_to( gender => 'My::Schema::Genders' );
1;
...
say $user->gender->name; #male
say $user->posts->first->title; # Как размножаются ёжики?
$user->add_to_posts( { title => 'RE: Как размножаются ёжики' } );
$user->posts->find( $post_id );
$user->search_related('posts')->search_related('comments', { order_by =>
'date' } );
12. Запросы
$schema->resultset('User')->find($id)
$v = $schema->resultset('Users')->search( { name => 'vasya' } );
$v->search( { gender => 'f' } )->count;
$user->messages->search( { text => { like => '%yandex%' } } )->delete;
man DBIx::Class::ResultSet
14. Prefetch
Нам нужно сэкономить на запросах
my $posts = $schema->resultset('Posts');
foreach my $row ($posts->all) {
say $post->forum->moderator->name;
}
15. Всего один запрос
my $posts = $schema->resultset('Posts')->search(undef,{
prefetch => {
forum => 'moderator'
}
});
foreach my $post ( $posts->all ) {
say $post->forum->moderator->name;
}
19. Inflate, Deflate
Мы получаем тип данных из базы и превращаем его в
красивый объект.
И наоборот
Например, мы можем прозрачно сохранять перловую
структуру в каком-то поле!!
man DBIx::Class::InflateColumn
22. DBIx::Class::DynamicSubclass
В зависимости от какого-то флагового поля в базе,
может создавать объекты других типов.
Получаем записи из таблицы Animals, а они сразу bless-
ятся в кошечек и собачек.