Mapping objet-relationnel

(en anglais Object Relational Mapping et donc ORM Library)

Un mapping objet-relationnel permet la manipulation et le contrôle de données d'une base de données relationnelle comme s'il s'agissait d'un objet PHP. Une fois que vous avez défini les correspondances entre la base de données et les objets du langage, le mapping objet-relationnel vous permet de déposer vos données en base, de les manipuler comme vous le désirez et sauvegarde les résultats sans utilisation de SQL.

En créant les relations entre les modèles cf. convention over configuration, bon nombre de répétitions d'écriture de requête comme create, read, update and delete peuvent être réduites voire effacées. L'ensemble des relations peuvent être gérer automatiquement par la librairie ORM et vous pouvez accéder aux données comme si c'était des propriétés d'objets standards.

Table des matières

*Si pour vous l'objet mapping relationnel est nouveau, commencez par lire cette section Getting Started

Les relations entre Mapping objet-relationnel et la librairie base de données

La majorité des questions relatives au mapping objet-relationnel sont liées au mode de fonctionnement de la librairie ORM utilisant la librairie base de données Database.

Il est important de comprendre que toutes les méthodes utilisées dans la librairie Base de données Database Query Builder sont présentes et utilisables sur les objets du mapping objet-relationnel.

Les seules méthodes qui ne fonctionnent pas sont :

  • au lieu de query() - utilisez les méthodes ORM find() et find_all() pour les requêtes de type Sélection, save() et delete() pour les insertion, les mises à jour et les effacements.
  • au lieu de get() - utilisez les méthodes ORM find() et find_all().
  • au lieu de insert() - utilisez la méthode save()
  • au lieu de update() - utilisez la méthode save()
  • au lieu de delete() - utilisez les méthodes delete() et delete_all()

Si vous ne comprenez pas la librairie du générateur de requêtes Database - vous devriez commencer par là avant de vous frotter aux usages du mapping objet-relationnel

Référentiel de l'api Mapping Objet-Relationnel

Voici des exemples les plus communément utilisés dans les méthodes ORM. Les propriétés sont listées en dessous pour faire une référence rapide. Merci de vous référer à cette page Kohana API Documentation pour obtenir la liste complète de toutes les méthodes et propriétés disponibles.

Méthodes

Toutes les méthodes publiques et les méthodes protégées de l'ORM sont listées ici.

factory

Cette méthode statique permet le chargement des objets ORM :

$object = ORM::factory($model_name, $row_id = NULL);

find

La méthode Find() se charge d'exécuter une requête sur la base de données, récupère un enregistrement et configure l'objet actuel selon le résultat obtenu.

// Cherche l'article avec une clé primaire égale à 1
$object = ORM::factory('article')->find(1);
echo $object->title;
// cherche un article selon son titre
$object = ORM::factory('article')->where('title', $title)->find();

Un objet est retourné même dans le cas où aucune donnée n'est trouvée. Pour tester si l'objet contient des résultats, il faut utiliser loaded.

find_all

La méthode Find_all() exécute une requête en base de données et retourne plusieurs enregistrements en utilisant l'itérateur ORM (un itérateur est un objet qui va parcourir tous les éléments d'un autre objet).

$articles = ORM::factory('article')->find_all();
foreach($articles as $article)
{
    echo $article->title;
}

Ainsi vous pouvez récupérer une partie des enregistrements en spécifiant des paramètres optionnels (à l'image du LIMIT utilisé pour MySQL. Attention, L'ordre des paramètres utilisé par MySQL est inversé [LIMIT [offset,] lignes]) Cf. http://dev.mysql.com/doc/refman/5.0/fr/select.html

$limit = 10;
$offset = 30;
// Ceci retournera 10 enregistrements depuis la ligne 30)
$articles = ORM::factory('article')->find_all($limit,$offset);

where

orwhere

save

Cette méthode sauvegarde l'objet courant en base de données. Si l'objet ne possède pas 'id' configuré, cela insérera un nouvel enregistrement sinon une mise à jour sera effectuée.

NB : Vous avez besoin d'appeler La méthode save() après les méthodes add() et Remove() pour sauvegarder vos modifications dans les tables concernées.

$article = ORM::factory('article', 1);
 
$article->title = 'New title';
$article->save();

Les nouveaux objets qui viennent d'être crées sont toujours rechargés après sauvegarde afin de récupérer les valeurs par défaut des colonnes n'ayant pas de valeurs.

clear

Cette méthode efface le statut d'un objet en le vidant pour être réutilisé.

$article = ORM::factory('article', 1);
 
// L'article est désormais vide
$article->clear();
 
var_dump($article->loaded); // Retourne le booléen faux (FALSE)

reload

Cette méthode recharge l'objet ORM depuis la base de données. Si $this→reload_on_wakeup est activé, unserializing un objet sera rechargé.

$article = ORM::factory('article', 1);
 
$article->title = 'un titre différent';
 
// Le titre de l'article sera initialisé avec le titre sauvegardé auparavant
$article->reload();
 
var_dump($article->title); // retournera le titre original

delete

La méthode delete() efface l'objet courant ou celui dont l'id correspond au paramètre passé.

$article = ORM::factory('article', 1);
$article->delete();
// ou
ORM::factory('article')->delete(1); // Utilise une requête au lieu de deux

delete_all

Cette méthode delete_all() efface plusieurs objets à la fois. Soit elle efface tous les objets du même type si aucun argument n'est passé, soit un tableau d'ID est passé pour spécifier les objets à effacer.

// efface tous les enregistrements du type article
ORM::factory('article')->delete_all();
 
// Efface les enregistrements dont l'id est inclu dans le tableau passé en argument : ici 1, 2, 4, et 5
ORM::factory('article')->delete_all(array(1,2,4,5));

La méthode delete_all() peut tout aussi bien effacer des enregistrements en se basant sur une condition.

// Efface tous les enregistrements dont l'id de catégorie est égal à 1
ORM::factory('article')->where(array('category_id' => 1))->delete_all();

as_array

Cette méthode retourne l'objet courant au format tableau.

$article = ORM::factory('article', 1)->as_array();
 
echo $article['title'];

select_list

Cette méthode génère un tableau contenant des paires de clés/valeurs de tous les objets. La fonction accepte deux noms de colonnes comme paramètres. La première colonne est la valeur et la seconde est le nom ou la description. Ceci est particulièrement utile quand on l'utilise conjointement avec le générateur de form automatisé pour construire automatiquement et remplir des menus.

Ce qui suit est un exemple qui génère des liens pour tous les articles qui sont suivis par un menu déroulant rempli avec l'ensemble des articles.

$articles = ORM::factory('article')->select_list('id', 'title');
 
foreach ($articles as $id => $title)
{
    // Affiche la liste de liens
    echo html::anchor('articles/'.$id, $title);
}
 
// affiche un menu déroulant
echo form::dropdown('articles', $articles);

has

Cette méthode test si un objet dispose de relations (cardinalités) avec un autre objet. Le code suivant testera si l'utilisateur dispose du rôle login (connexion). Cette méthode retourne toujours un booléen.

$user = ORM::factory('user', 1);
 
// Retourne la relation selon la clé primaire.
$user->has(ORM::factory('role', 1));
 
// ou si vous avez surchargé la méthode ORM::unique_key() dans votre modèle pour permettre de retourner des résultats depuis d'autres colonnes à valeur unique
$user->has(ORM::factory('role', 'login'));

add

Cette méthode ajoute une relation à un objet à d'autres. Le code suivant ajoute le rôle administrateur à un utilisateur. NB : vous noterez qu'il faut appeler la méthode save() pour confirmer l'addition des relations entre les obejts. La librairie ORM ne le fait pas automatiquement.

$user = ORM::factory('user', 1);
 
$user->add(ORM::factory('role', 'admin'));
 
$user->save();

Alternative syntax une alternative vous permet d'ajouter des relations entre objets avec une table pivot en utilisant un tableau de la forme array(id, id).

remove

Cette méthode supprime la relation d'un objet vers d'autres. Le code suivant supprimera le rôle login pour un utilisateur donné. Vous devez appeler la méthode save() pour supprimer les relations et les enregistrements relatifs à cette relation. La librairie ORM ne sauvegarde pas automatiquement les modifications.

$user = ORM::factory('user', 1);
 
$user->remove(ORM::factory('role', 'login'));
 
$user->save();

Alternative syntax une alternative vous permet d'ajouter/modifier de multiples relations avec l'utilisation d'un tableau pivot du type array(id, id). Les ID non présents dans le tableau seront supprimés.

with

Cette méthode est liée aux relations de type 1 à 1 utilisant une jointure de type JOIN. Cela est utile dans les situations où vous ne voulez pas utiliser la chargement par défaut pour améliorer les performances. Vous pouvez donc les emboîtés un à un en utilisant un pointeur d'objet.

// Cela utilise une requête SQL pour récupérer un utilisateur, la vie associée et le pays.
$users = ORM::factory('user')->with('city')->with('city:country')->find_all();
 
foreach($users as $user) {
  echo $user->city->country->name;
}

Vous pouvez aussi configurer la propriété $load_with du modèle ORM pour automatiser les rattachements.

foreign_key()

Cette fonction publique revêt la forme “foreign_key($table = NULL, $prefix_table = NULL)”. Elle retourne le nom de la clé étrangère d'une table spécifiée.

Les paramètres sont :

  1. une chaîne, un booléen, une valeur nulle
  2. une chaîne ou une valeur nulle.
// Cela équivaut à faire : $model->object_name.'_'.$model->primary_key soit 'user_id'
$join_col = $model->foreign_key();
 
// Cela équivaut à faire : $model->object_name.'.'.$model->primary_key soit 'user.id'
$join_col = $model->foreign_key(TRUE);
 
//  Cela équivaut à faire : $join_table.'.'.$model->object_name.'_'.$model->primary_key soit 'blogs_users.user_id'
$join_col = $model->foreign_key(NULL,$join_table);

Aller consulter la propriété protégée $foreign_key.

join_table()

Cette méthode publique est définie comme public function join_table($table)

Un ordonnancement alphabétique est effectué pour le choix de la table servant à faire la jointure.

Paramètre :

  1. Le nom de la table sur laquelle on fait la jointure est une chaîne.

Cela permet de créer : $model→table_name'_'.$table ou $table.'_'.$model→table_name

Exemple: La table de jointure entre 'users' et 'roles' serait 'roles_users' à cause du “r” de la table roles qui précède le “u” de users. Joindre les tables 'products' et 'categories' retourne les résultats dans 'categories_products', à cause du “c” qui vient avant le “p”.

$user = ORM::factory('user');
echo $user->join_table('roles'); // roles_users

L'ordre est celui de l'anglais standard : zoo > zebra > robber > ocean > angel > aardvark

count_all()

Permet de compter tous les résultats

Example:

$db = ORM::factory('article')->where('tags', 'bali');
echo $db->count_all();

count_last_query()

Cette méthode compte combien de résultats ont été trouvé lors de la dernière requête.

Exemple:

$db = ORM::factory('user')->where('hometown', 'bali');
echo $db->count_last_query();

Propriétés

Le Mapping Relationnel Objet (ORM en anglais) dispose de plusieurs propriétés publiques sur les objets utilisables pour différents buts.

Par défaut, toutes ces propriétés sont gérées par l'ORM et changeront dynamiquement sur la base de l'objet. Elles ne devraient jamais faire l'objet d'une configuration manuelle dans un modèle.

loaded (Chargé)

Ce booléen permet de savoir si l'objet courant a été chargé depuis la base de données. Cela est utilisé pour tester si l'objet est chargé avec succès.

$article = ORM::factory('article', 1);
 
if ($article->loaded==TRUE)
{
    echo 'article chargé', $article->id;
}
else
{
    echo 'aucun article ne correspond à cette id';
}

changed (Modifié)

Les tableaux utilisés par l'ORM servent à tracker les changements effectués sur les colonnes dans un model ORM avant d'enregistrer. Vous pouvez vérifier le statut d'une colonne spécifique en utilisant isset($this→changed['name']).

La propriété changed (modifié) est très utile dans le cas d'une surcharge de la méthode save() dans votre modèle ORM. Surcharger la méthode save() vous permet de réaliser des traitements supplémentaires, des filtrages ou des vérifications d'intégrité avant de sauver/mettre à jour vos données dans votre modèle ORM.

// surcharge de la méthode save() dans votre modèle ORM
 
public function save()
{
    if (isset($this->changed['name'])) 
    {			
        // configure set the slug when the name changes -- 'my-post-name'
	$this->slug = url::title($this->name);		
    }
}

saved (Sauvegardé)

Ce booléen vous permet de contrôler si l'objet courant est sauvegardé.

$article = ORM::factory('article', 1);
 
if($article->saved==FALSE)
{
    echo 'pas sauvegardé';
}
 
$article->save();
 
if($article->saved==TRUE)
{
    echo 'sauvegardé';
}

object_name (Nom de l'objet)

Cette propriété retourne simplement le nom de l'objet. Si la classe est nommée Blog_Post_Model, alors Blog_Post est le nom de l'objet

primary_key (Clé primaire)

Cette propriété renvoi le nom de la colonne faisant office de clé primaire.

// Cet exemple utilise le champ 'usercode' comme clé primaire
class User_Model extends ORM {
 
    protected $primary_key = 'usercode';
 
}

primary_val (Valeur pratique)

Cette propriété permet de choisir une valeur pratique pour une colonne dans une table. Par défaut, c'est le nom qui est utilisé (name). Pour des raisons pratiques et pour faciliter l'identification des informations vous pouvez ainsi utiliser cette propriété. Si vous avez une table users, vous pouvez la changer pour username.

class User_Model extends ORM {
 
    protected $primary_val = 'username';
 
}

table_name (nom de la table)

Cette propriété stocke le nom de la table contenant les enregistrements.

// Cet exemple utilise le nom 'usuarios' pour la table 'User_Model'
class User_Model extends ORM {
 
    protected $table_name = 'usuarios';
 
}

table_columns (colonnes de la table)

Cette propriété permet d'accéder aux informations des colonnes composant une table

class User_Model extends ORM {
 
    protected $table_columns = array('id','username','last_login','anotherfield');
 
}

sorting (tri)

Cette propriété permet de configurer un tableau de paramètres de tri afin de les appliquer aux requêtes. Par défaut, les résustats sont triés par id croissant id ASC. Vous pouvez ajouter plusieurs colonnes et types de tri.

class User_Model extends ORM {
 
    protected $sorting = array('last_login' => 'desc', 'username' => 'asc');
 
}

load_with (charge avec)

Cette propriété vous permet de spécifier quelles relations devraient toujours être jointent.

class Blog_Post_Model extends ORM {
 
    protected $load_with = array('user');
 
}
libraries/orm.txt · Dernière modification: 10/03/2011 01:15 par koyott
CC Attribution-Noncommercial-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0