🗊Rose::DB Perl ORM Быстрый страт

Категория: Технологии
Нажмите для полного просмотра!
Rose::DB  Perl  ORM           Быстрый страт, слайд №1Rose::DB  Perl  ORM           Быстрый страт, слайд №2Rose::DB  Perl  ORM           Быстрый страт, слайд №3Rose::DB  Perl  ORM           Быстрый страт, слайд №4Rose::DB  Perl  ORM           Быстрый страт, слайд №5Rose::DB  Perl  ORM           Быстрый страт, слайд №6Rose::DB  Perl  ORM           Быстрый страт, слайд №7Rose::DB  Perl  ORM           Быстрый страт, слайд №8Rose::DB  Perl  ORM           Быстрый страт, слайд №9Rose::DB  Perl  ORM           Быстрый страт, слайд №10Rose::DB  Perl  ORM           Быстрый страт, слайд №11Rose::DB  Perl  ORM           Быстрый страт, слайд №12Rose::DB  Perl  ORM           Быстрый страт, слайд №13Rose::DB  Perl  ORM           Быстрый страт, слайд №14

Вы можете ознакомиться и скачать Rose::DB Perl ORM Быстрый страт. Презентация содержит 14 слайдов. Презентации для любого класса можно скачать бесплатно. Если материал и наш сайт презентаций Вам понравились – поделитесь им с друзьями с помощью социальных кнопок и добавьте в закладки в своем браузере.

Слайды и текст этой презентации


Слайд 1





Rose::DB
Perl
ORM
         Быстрый страт
Описание слайда:
Rose::DB Perl ORM Быстрый страт

Слайд 2





Создаём класс с коннектом к базе
Создаём класс с коннектом к базе

package My::DB;
use warnings;
use strict;
use base qw(Rose::DB);
__PACKAGE__->use_private_registry;
__PACKAGE__->register_db(
      driver   => 'mysql',
      type	   => 'main',
      database => 'databasename',
      host     => '*****.***.***',
      username => 'user',
      password => '*****',
      connect_options =>
      {         
		AutoCommit => 1,
	    	RaiseError => 1,       
	}
); 
1;
Описание слайда:
Создаём класс с коннектом к базе Создаём класс с коннектом к базе package My::DB; use warnings; use strict; use base qw(Rose::DB); __PACKAGE__->use_private_registry; __PACKAGE__->register_db( driver => 'mysql', type => 'main', database => 'databasename', host => '*****.***.***', username => 'user', password => '*****', connect_options => { AutoCommit => 1, RaiseError => 1, } ); 1;

Слайд 3





При этом, учитываем, что в Rose::DB существует 2 параметра подключения к базе: 
При этом, учитываем, что в Rose::DB существует 2 параметра подключения к базе: 
type и domain. Т.о. вы можете варьировать между девелоперской и продакшн 
базой с одинаковыми структурами данных. Для это можно описать несколько
вызовов метода register_db.
В документации приводится даже пример:

    use My::DB;
    if($ENV{'MYCORP_PRODUCTION_SERVER'})
    {
      	My::DB->default_domain('production');
    }
    else
    {
      	My::DB->default_domain('development');
    }
Аналогично можно указывать и default_type для коннекта. 
Rose::DB::Cache – тут описывается вариант работы под mod_perl с/без использования Apache::DBI
Описание слайда:
При этом, учитываем, что в Rose::DB существует 2 параметра подключения к базе: При этом, учитываем, что в Rose::DB существует 2 параметра подключения к базе: type и domain. Т.о. вы можете варьировать между девелоперской и продакшн базой с одинаковыми структурами данных. Для это можно описать несколько вызовов метода register_db. В документации приводится даже пример: use My::DB; if($ENV{'MYCORP_PRODUCTION_SERVER'}) { My::DB->default_domain('production'); } else { My::DB->default_domain('development'); } Аналогично можно указывать и default_type для коннекта. Rose::DB::Cache – тут описывается вариант работы под mod_perl с/без использования Apache::DBI

Слайд 4





Выливаем классы таблиц из базы
Выливаем классы таблиц из базы

#!/usr/bin/perl
use strict;
use warnings;
use lib '/home/****/';
use My::DB;
use Rose::DB::Object::Loader;
   
	my $loader = Rose::DB::Object::Loader->new(
      		db => My::DB->new('main'),
      		class_prefix => 'My::DB',
			with_foreign_keys => 1,
			with_relationships => 1
    );
$loader->make_modules(module_dir=>'/home/****/',exclude_tables=>'Tmp');
exit;
В данном случае передаётся доп параметр 'Tmp', чтобы исключить таблицы /Tmp/ (regexp) из итогового набора таблиц.
При этом учитываем, что если у вас уже есть классы с описанием таблиц (со своими кастомными добавками), то они просто перезатрутся.
Так же нужно учитывать, что если у вас есть поля с типом char(х), то это будет отмечено в калссах, и когда вы будете забирать значения из из объекта строки для данной таблицы, значение будет дополнено пробелами до «x» символов.
Описание слайда:
Выливаем классы таблиц из базы Выливаем классы таблиц из базы #!/usr/bin/perl use strict; use warnings; use lib '/home/****/'; use My::DB; use Rose::DB::Object::Loader; my $loader = Rose::DB::Object::Loader->new( db => My::DB->new('main'), class_prefix => 'My::DB', with_foreign_keys => 1, with_relationships => 1 ); $loader->make_modules(module_dir=>'/home/****/',exclude_tables=>'Tmp'); exit; В данном случае передаётся доп параметр 'Tmp', чтобы исключить таблицы /Tmp/ (regexp) из итогового набора таблиц. При этом учитываем, что если у вас уже есть классы с описанием таблиц (со своими кастомными добавками), то они просто перезатрутся. Так же нужно учитывать, что если у вас есть поля с типом char(х), то это будет отмечено в калссах, и когда вы будете забирать значения из из объекта строки для данной таблицы, значение будет дополнено пробелами до «x» символов.

Слайд 5





Допустим у вас есть класс My::DB::MlPerson для получения объекта строки, 
Допустим у вас есть класс My::DB::MlPerson для получения объекта строки, 
с person_id достаточно дать:
$p = My::DB::MlPerson->new(person_id=>74952020)->load
В конструктор передаётся первичный или уникальный ключ.
 «Прогрузка» данных произойдёт только в момент load.
Может так случиться, что в базе нет строки с укзанным значением ключа, и тогда вам вернётся warn. Поскольку иметь такие отбивки не интересно, да и не наглядно, рекомендуется использовать конструкцию с использованием параметра speculative:
unless($p->load(speculative => 1)) {
	warn "not found";
}
Получим и изменим значение поля password для нашей персоны:
$p->password;
$p->password('new_pass');
При установке значения в поле, проверяется его валидность на соответствие в описании класса.
Сохраним изменённый объект строки в базе (update):
$p->save;
Создадим новую запись в базе:
$p = My::DB::MlPerson->new(person_id=>74952020,password=>'pass');
$p->save;
В данном контексте (создание записи), в конструктор совсем необязательно передавать авто-инкрементируемый ключ.
Удаление записей абсолютно бесхитростно:
$p = My::DB::MlPerson->new(person_id=>74952020);
$p->delete;
Как видно, load в данном случае не требуется.
Описание слайда:
Допустим у вас есть класс My::DB::MlPerson для получения объекта строки, Допустим у вас есть класс My::DB::MlPerson для получения объекта строки, с person_id достаточно дать: $p = My::DB::MlPerson->new(person_id=>74952020)->load В конструктор передаётся первичный или уникальный ключ. «Прогрузка» данных произойдёт только в момент load. Может так случиться, что в базе нет строки с укзанным значением ключа, и тогда вам вернётся warn. Поскольку иметь такие отбивки не интересно, да и не наглядно, рекомендуется использовать конструкцию с использованием параметра speculative: unless($p->load(speculative => 1)) { warn "not found"; } Получим и изменим значение поля password для нашей персоны: $p->password; $p->password('new_pass'); При установке значения в поле, проверяется его валидность на соответствие в описании класса. Сохраним изменённый объект строки в базе (update): $p->save; Создадим новую запись в базе: $p = My::DB::MlPerson->new(person_id=>74952020,password=>'pass'); $p->save; В данном контексте (создание записи), в конструктор совсем необязательно передавать авто-инкрементируемый ключ. Удаление записей абсолютно бесхитростно: $p = My::DB::MlPerson->new(person_id=>74952020); $p->delete; Как видно, load в данном случае не требуется.

Слайд 6





Теперь перейдём к вопросам более сложных запросов в базу
Теперь перейдём к вопросам более сложных запросов в базу

Когда вы выливали структуру таблицы в классы, то для каждой таблицы
были созданы 2 модуля (на примере MlPerson):
My::DB::MlPerson
My::DB::MlPerson::Manager
Идеология состоит в том, что если вам требуется создать некий дополнительный метод для таблицы, который бы возвращал обработанное значение имеющихся полей, то это удобно делать в My::DB::MlPerson.
Примером является случай, когда у вас в поле хранится сериализованная структура данных. Скажем, сериализованная через Storable. Пример для такого поля stor_field:

package My::DB::MlPerson;
….
use Storable qw(thaw freeze);
$Storable::interwork_56_64bit = 1;
sub alias_to_stor_field{
	my ($row_obj,$new_val) = @_;
	if ($new_val and ref $new_val) {
		# ставим новое значение
		$row_obj->stor_field(freeze($new_val));
		return 1;
	} elsif ($row_obj->stor_field) {
		# десериализуем имеющееся
		return thaw($row_obj->stor_field);
	};
	return undef;
}
Описание слайда:
Теперь перейдём к вопросам более сложных запросов в базу Теперь перейдём к вопросам более сложных запросов в базу Когда вы выливали структуру таблицы в классы, то для каждой таблицы были созданы 2 модуля (на примере MlPerson): My::DB::MlPerson My::DB::MlPerson::Manager Идеология состоит в том, что если вам требуется создать некий дополнительный метод для таблицы, который бы возвращал обработанное значение имеющихся полей, то это удобно делать в My::DB::MlPerson. Примером является случай, когда у вас в поле хранится сериализованная структура данных. Скажем, сериализованная через Storable. Пример для такого поля stor_field: package My::DB::MlPerson; …. use Storable qw(thaw freeze); $Storable::interwork_56_64bit = 1; sub alias_to_stor_field{ my ($row_obj,$new_val) = @_; if ($new_val and ref $new_val) { # ставим новое значение $row_obj->stor_field(freeze($new_val)); return 1; } elsif ($row_obj->stor_field) { # десериализуем имеющееся return thaw($row_obj->stor_field); }; return undef; }

Слайд 7





Но вот когда нам требуется обработать набор строк, вступает в свою силу My::DB::MlPerson::Manager.
Но вот когда нам требуется обработать набор строк, вступает в свою силу My::DB::MlPerson::Manager.
В самом модуле вы увидите:

__PACKAGE__->make_manager_methods('НазваниеТаблицыВБазе');
Этот метод делает доступными следующие методы для класса My::DB::MlPerson::Manager:

    get_НазваниеТаблицыВБазе
    get_НазваниеТаблицыВБазе_iterator
    get_НазваниеТаблицыВБазе_count
    delete_НазваниеТаблицыВБазе
    update_НазваниеТаблицыВБазе
Итак, для нашей таблицы ml_person, это будут:
My::DB::MlPerson::Manager->get_ml_person
возвращает ссылку на массив всех строк в таблице (что удобно в очень редких случаях, когда обращаешься по индексу, а не разыменовываешь массив. И, всё равно, не удобно.)
My::DB::MlPerson::Manager->get_ml_person_iterator
возвращает итератор для обхода всей таблицы.

my $i = My::DB::MlPerson::Manager->get_ml_person_iterator;
while( my $p = $i->next ) {
      print $p->name;
      $i->finish  if(...);
}
Ахтунг на лицо. И всё было бы совсем плохо, НО …
Описание слайда:
Но вот когда нам требуется обработать набор строк, вступает в свою силу My::DB::MlPerson::Manager. Но вот когда нам требуется обработать набор строк, вступает в свою силу My::DB::MlPerson::Manager. В самом модуле вы увидите: __PACKAGE__->make_manager_methods('НазваниеТаблицыВБазе'); Этот метод делает доступными следующие методы для класса My::DB::MlPerson::Manager: get_НазваниеТаблицыВБазе get_НазваниеТаблицыВБазе_iterator get_НазваниеТаблицыВБазе_count delete_НазваниеТаблицыВБазе update_НазваниеТаблицыВБазе Итак, для нашей таблицы ml_person, это будут: My::DB::MlPerson::Manager->get_ml_person возвращает ссылку на массив всех строк в таблице (что удобно в очень редких случаях, когда обращаешься по индексу, а не разыменовываешь массив. И, всё равно, не удобно.) My::DB::MlPerson::Manager->get_ml_person_iterator возвращает итератор для обхода всей таблицы. my $i = My::DB::MlPerson::Manager->get_ml_person_iterator; while( my $p = $i->next ) { print $p->name; $i->finish if(...); } Ахтунг на лицо. И всё было бы совсем плохо, НО …

Слайд 8





НО эти методы умеют принимать аргументы для уточнения результатов поиска и возврата соответствующей ссылки на массив или итератор:
НО эти методы умеют принимать аргументы для уточнения результатов поиска и возврата соответствующей ссылки на массив или итератор:

my $i = My::DB::MlPerson::Manager->get_ml_person_iterator(
      query => [
          name => {like => '%Hat'},
          person_id   => {ge => 7},
          or   =>  [
              age => 15,
              age => {lt => 10},
          ],
      ],
      sort_by => 'name',
      limit   => 10,
      offset  => 50
);
while( my $p = $i->next ) {
      print $p->name;
      $i->finish  if(...);
}
Эти аргументы эквивалентны квере:

   SELECT person_id, name, age,…,password FROM ml_person WHERE
      name LIKE '%Hat' AND
      person_id >= 7 AND
      (age = 15 OR age < 10.00)
    ORDER BY name
    LIMIT 10 OFFSET 50
Описание слайда:
НО эти методы умеют принимать аргументы для уточнения результатов поиска и возврата соответствующей ссылки на массив или итератор: НО эти методы умеют принимать аргументы для уточнения результатов поиска и возврата соответствующей ссылки на массив или итератор: my $i = My::DB::MlPerson::Manager->get_ml_person_iterator( query => [ name => {like => '%Hat'}, person_id => {ge => 7}, or => [ age => 15, age => {lt => 10}, ], ], sort_by => 'name', limit => 10, offset => 50 ); while( my $p = $i->next ) { print $p->name; $i->finish if(...); } Эти аргументы эквивалентны квере: SELECT person_id, name, age,…,password FROM ml_person WHERE name LIKE '%Hat' AND person_id >= 7 AND (age = 15 OR age < 10.00) ORDER BY name LIMIT 10 OFFSET 50

Слайд 9





Далее,
Далее,

My::DB::MlPerson::Manager->get_ml_person_count
возвращает число записей в таблице. Так же умеет принимать аргументы, чтобы конкретизировать where в запросе на подсчёт.

My::DB::MlPerson::Manager->delete_ml_person
удаляет записи в соответствии с переданными аргументами.

My::DB::MlPerson::Manager->update_ml_person
обновляет записи в соответствии с переданными аргументами.

Здесь стоит отметить, как передаётся аргумент set в кверю:
My::DB::MlPerson::Manager->update_ml_person(
        set =>
        {
          age => 25,
        },
        where =>
        [
          age => 24,
          person_id    => { gt => 100 },
        ]
);
В любом из классов-описаний таблиц, вы можете выбрать стиль подключения, если перегрузите метод:
Собственное подключение к базе: sub init_db { My::DB->new }
Использовать уже созданное или новое: sub init_db { My::DB->new_or_cached }
Описание слайда:
Далее, Далее, My::DB::MlPerson::Manager->get_ml_person_count возвращает число записей в таблице. Так же умеет принимать аргументы, чтобы конкретизировать where в запросе на подсчёт. My::DB::MlPerson::Manager->delete_ml_person удаляет записи в соответствии с переданными аргументами. My::DB::MlPerson::Manager->update_ml_person обновляет записи в соответствии с переданными аргументами. Здесь стоит отметить, как передаётся аргумент set в кверю: My::DB::MlPerson::Manager->update_ml_person( set => { age => 25, }, where => [ age => 24, person_id => { gt => 100 }, ] ); В любом из классов-описаний таблиц, вы можете выбрать стиль подключения, если перегрузите метод: Собственное подключение к базе: sub init_db { My::DB->new } Использовать уже созданное или новое: sub init_db { My::DB->new_or_cached }

Слайд 10





Вы всегда можете получить объект My::DB
Вы всегда можете получить объект My::DB

    $p = My::DB::MlPerson->new(...);
    $db = $p->db;
И, организовать транзакционный механизм (если автокоммит отключен):

    $p = My::DB::MlPerson->new(...);
    $db = $p->db;
    $db->begin_work; # Начало транзакции
    # Используем наш $db для каждого создаваемого объекта-строки
    $p1 = My::DB::MlPerson->new(name => 'Bike', db => $db);
    $p1->save;
    $p2 = My::DB::MlPerson->new(name => 'Sled', db => $db);
    $p2->save;
    $p3 = My::DB::MlPerson->new(name => 'Kite', db => $db);
    $p3->save;
    if(...) # Применяем изменения или откатываемся
    {
      		$db->commit;
    }
    else
    {
      		$db->rollback;    
    };
А теперь вернёмся к My::DB и возможности регистрировать несколько коннектов к базам, играя параметрами type и domain.
Описание слайда:
Вы всегда можете получить объект My::DB Вы всегда можете получить объект My::DB $p = My::DB::MlPerson->new(...); $db = $p->db; И, организовать транзакционный механизм (если автокоммит отключен): $p = My::DB::MlPerson->new(...); $db = $p->db; $db->begin_work; # Начало транзакции # Используем наш $db для каждого создаваемого объекта-строки $p1 = My::DB::MlPerson->new(name => 'Bike', db => $db); $p1->save; $p2 = My::DB::MlPerson->new(name => 'Sled', db => $db); $p2->save; $p3 = My::DB::MlPerson->new(name => 'Kite', db => $db); $p3->save; if(...) # Применяем изменения или откатываемся { $db->commit; } else { $db->rollback; }; А теперь вернёмся к My::DB и возможности регистрировать несколько коннектов к базам, играя параметрами type и domain.

Слайд 11





Пусть у нас будут описаны в My::DB два коннекта для баз с одинаковыми 
Пусть у нас будут описаны в My::DB два коннекта для баз с одинаковыми 
структурами. Одна с domain=>’production’ и вторая с domain=>’archive’. 
Назначение баз понятно.

    $production_db = My::DB->new('production');
    $archive_db    = My::DB->new('archive');
    # Загрузим с продакшн базы данные по конкретной персоне
    $p = My::DB::MlPerson->new(person_id => 'John', db => $production_db);
    $p->load;
    # Скопируем данные по персоне в архив
    $p->db($archive_db);
    $p->save(insert => 1); # аргумент insert позволит либо записать строку, либо обновить значения 
    # Удалим обозначенную персону из продакшн базы 
    $p->db($production_db);
    $p->delete;
Рассмотрим зависимости.
Если у вас в базе они не были проставлены, то при генерации классов-таблиц, вы их то же не увидите.

Прелесть в том, что можно прописать их ручками.
Описание слайда:
Пусть у нас будут описаны в My::DB два коннекта для баз с одинаковыми Пусть у нас будут описаны в My::DB два коннекта для баз с одинаковыми структурами. Одна с domain=>’production’ и вторая с domain=>’archive’. Назначение баз понятно. $production_db = My::DB->new('production'); $archive_db = My::DB->new('archive'); # Загрузим с продакшн базы данные по конкретной персоне $p = My::DB::MlPerson->new(person_id => 'John', db => $production_db); $p->load; # Скопируем данные по персоне в архив $p->db($archive_db); $p->save(insert => 1); # аргумент insert позволит либо записать строку, либо обновить значения # Удалим обозначенную персону из продакшн базы $p->db($production_db); $p->delete; Рассмотрим зависимости. Если у вас в базе они не были проставлены, то при генерации классов-таблиц, вы их то же не увидите. Прелесть в том, что можно прописать их ручками.

Слайд 12





Отредактируем My::DB::MlPerson и добавим в метод setup вот такой аргумет:
Отредактируем My::DB::MlPerson и добавим в метод setup вот такой аргумет:

      foreign_keys =>
      [
        crm =>
        {
          class       => 'My::DB::CrmBridge',
          key_columns => { person_id => 'f_person_id' },
		   relationship_type => 'one to one',
        },
	]
Итак, что у нас здесь:
создана связь между классами (не таблицами): My::DB::MlPerson и My::DB::CrmBridge.
следующим образом:
ml_person.person_id является внешним ключом для crm_bridge.f_person_id. Соответствие определено как один-к-одному. Обращение к отноению идёт по методу с именем crm. 
relationship_type может так же быть записан как rel_type (синоним)
И, теперь мы можем сделать вот такую штуку:

$p = My::DB::MlPerson->new(person_id=>74952020)->load;
$p->crm->any_field
где, any_field  - это любое поле из таблицы crm_bridge.
Описание слайда:
Отредактируем My::DB::MlPerson и добавим в метод setup вот такой аргумет: Отредактируем My::DB::MlPerson и добавим в метод setup вот такой аргумет: foreign_keys => [ crm => { class => 'My::DB::CrmBridge', key_columns => { person_id => 'f_person_id' }, relationship_type => 'one to one', }, ] Итак, что у нас здесь: создана связь между классами (не таблицами): My::DB::MlPerson и My::DB::CrmBridge. следующим образом: ml_person.person_id является внешним ключом для crm_bridge.f_person_id. Соответствие определено как один-к-одному. Обращение к отноению идёт по методу с именем crm. relationship_type может так же быть записан как rel_type (синоним) И, теперь мы можем сделать вот такую штуку: $p = My::DB::MlPerson->new(person_id=>74952020)->load; $p->crm->any_field где, any_field - это любое поле из таблицы crm_bridge.

Слайд 13





В общем-то, в данном случае можно было бы и опустить rel_type. 
В общем-то, в данном случае можно было бы и опустить rel_type. 
Да и к тому же, можено вообще вынести этот аргумент в виде вызова 
метода (но очь важно, чтобы это было определено до вызова setup):

package My::DB::MlPerson;
__PACKAGE__->meta->foreign_keys(
      'crm' => {
      	class       => 'My::DB::CrmBridge',
      	key_columns => { person_id => 'f_person_id' }
      }
);
__PACKAGE__->meta->setup(…………)
А вот, интересный случай когда персона входит в несколько групп (в том же классе My::DB::MlPerson до setup):

__PACKAGE__->meta->relationships
  (
    group =>
    {
      type       => 'one to many',
      class      => 'My::DB::MlGroup',
      column_map => { person_id => 'f_person_id' },
    },
  );
Здесь обозначено отношение один-ко-многим (одна персона из ml_persons может иметь несколько записей в ml_group). Как уже понятно, можно обозначит это отношение и в виде аргумента в методе setup, если вам так удобнее.
Описание слайда:
В общем-то, в данном случае можно было бы и опустить rel_type. В общем-то, в данном случае можно было бы и опустить rel_type. Да и к тому же, можено вообще вынести этот аргумент в виде вызова метода (но очь важно, чтобы это было определено до вызова setup): package My::DB::MlPerson; __PACKAGE__->meta->foreign_keys( 'crm' => { class => 'My::DB::CrmBridge', key_columns => { person_id => 'f_person_id' } } ); __PACKAGE__->meta->setup(…………) А вот, интересный случай когда персона входит в несколько групп (в том же классе My::DB::MlPerson до setup): __PACKAGE__->meta->relationships ( group => { type => 'one to many', class => 'My::DB::MlGroup', column_map => { person_id => 'f_person_id' }, }, ); Здесь обозначено отношение один-ко-многим (одна персона из ml_persons может иметь несколько записей в ml_group). Как уже понятно, можно обозначит это отношение и в виде аргумента в методе setup, если вам так удобнее.

Слайд 14





Что сразу не понравилось:
Что сразу не понравилось:

 $p = My::DB::MlPerson->new(person_id=>74952020)->load;
$bor = $p->group;
ref $bor eq 'ARRAY';
другими словами – при обращении к отношению, вы получаете ссылку на массив или массив (в зависимости от контекста). На лицо явная избыточность. По документации не нашёл, как получить возможность обратиться к отношению с возможностью уточнения запроса (типа выбрать только конкретные группы для персоны) без выгребания всех записей из ml_group. И уж тем более, в продакшн всегда интереснее получить итератор, а тут #@я!

И, более того, по дефолту (а это очевидно настраивается), повторное обращение:
$p->group;
уже не стало лезть в базу (а ведь со стороны кто-то мог поменять значение в строках таблицы), а просто отдало значение из Кеша (!).

В общем, в данном вопросе, имхо, рулит DBIx::Class.

Что можно назвать удобным, так это удаление групп, в которых состоит персона:
$p = My::DB::MlPerson->new(person_id=>74952020)->load;
$p->group([ ]);
$p->save;
А вот пример тотально удаления всех связанных строк:
$p->delete(cascade => 1);
Для углубления вопроса по тому как составлять квери, рекомендую посмотреть Rose::DB::Object::Manager, где к сожалению не нашёл примера по вызову хранимок.

Тему сисек считаю не раскрытой, но для быстрого старта – вполне достаточно.
Описание слайда:
Что сразу не понравилось: Что сразу не понравилось: $p = My::DB::MlPerson->new(person_id=>74952020)->load; $bor = $p->group; ref $bor eq 'ARRAY'; другими словами – при обращении к отношению, вы получаете ссылку на массив или массив (в зависимости от контекста). На лицо явная избыточность. По документации не нашёл, как получить возможность обратиться к отношению с возможностью уточнения запроса (типа выбрать только конкретные группы для персоны) без выгребания всех записей из ml_group. И уж тем более, в продакшн всегда интереснее получить итератор, а тут #@я! И, более того, по дефолту (а это очевидно настраивается), повторное обращение: $p->group; уже не стало лезть в базу (а ведь со стороны кто-то мог поменять значение в строках таблицы), а просто отдало значение из Кеша (!). В общем, в данном вопросе, имхо, рулит DBIx::Class. Что можно назвать удобным, так это удаление групп, в которых состоит персона: $p = My::DB::MlPerson->new(person_id=>74952020)->load; $p->group([ ]); $p->save; А вот пример тотально удаления всех связанных строк: $p->delete(cascade => 1); Для углубления вопроса по тому как составлять квери, рекомендую посмотреть Rose::DB::Object::Manager, где к сожалению не нашёл примера по вызову хранимок. Тему сисек считаю не раскрытой, но для быстрого старта – вполне достаточно.



Похожие презентации
Mypresentation.ru
Загрузить презентацию