2010-03-26 5 views
1

Alors, laisse dire que j'ai un dossier:Mise à jour des données par le biais d'objets

$record = new Record(); 

et permet de dire que j'attribue des données à cet enregistrement:

$record->setName("SomeBobJoePerson"); 

Comment puis-je obtenir cela dans la base de données. Est-ce que je ...

A) Demandez au module de le faire.

class Record{ 
    public function __construct(DatabaseConnection $database) 
    { 
     $this->database = $database; 
    } 
    public function setName($name) 
    { 
     $this->database->query("query stuff here"); 
     $this->name = $name; 
    } 
} 

B) Courez à travers les modules à la fin du script

class Record{ 
    private $changed = false; 
    public function __construct(array $data=array()) 
    { 
     $this->data = $data; 
    } 
    public function setName($name) 
    { 
     $this->data['name'] = $name; 
     $this->changed = true; 
    } 
    public function isChanged() 
    { 
     return $this->changed; 
    } 
    public function toArray() 
    { 
     return $this->array; 
    } 
} 
class Updater 
{ 
    public function update(array $records) 
    { 
     foreach($records as $record) 
     { 
      if($record->isChanged()) 
      { 
       $this->updateRecord($record->toArray()); 
      } 

     } 
    } 
    public function updateRecord(){ // updates stuff 
    } 


} 

Répondre

0

Cela dépend de la façon dont vous envisagez d'implémenter ... Faire toutes les écritures à un seul point (à la fin de une requête) est sympa car elle vous permet d'optimiser vos opérations en consolidant les requêtes si possible. Mais pour ce faire, vous devez créer quelque chose de similaire à un UnitOfWork pour garder une trace de ce qui est une suppression/mise à jour/insertion qui peut ouvrir une autre boîte de Pandore. D'autre part, si vous le faites directement lorsque vous appelez la méthode de persistance sur l'entité, vous n'avez pas à vous en soucier autant. Les deux approches signifient cependant que vous devez avoir un moyen de vous assurer que vous avez toujours les données actuelles dans votre objet, mais le travail requis pour la mise en œuvre qui varie en complexité avec l'approche que vous choisissez.

0

L'exemple A met à jour la base de données à chaque appel de setName. Cette fonction ressemble à un simple accesseur d'écriture, mais elle effectue des actions coûteuses lorsqu'elle est appelée (connexion à la base de données, exécution d'une requête, etc.). Ces effets de site involontaires rendent l'exemple B beaucoup plus attrayant. Comme exemple supplémentaire: Vous aurez peut-être besoin ultérieurement d'une classe Validator qui examine un enregistrement et s'assure que l'enregistrement est dans un état valide. Mais pour examiner l'enregistrement, vous devez d'abord le définir en définissant un nom, afin que l'enregistrement soit conservé avant de pouvoir valider son état. La définition de l'état de l'objet est différente de l'état de l'objet persistant.

Une approche de modèle de données pourrait fonctionner mieux au lieu d'une approche basée sur des enregistrements. Par exemple:

class Model { 

     protected $_props= array(); 

     public $changed= false; 

     static public $models= array(); 

     function __set($name, $value) { 
      $this->changed= true; 
      $this->_props[$name]= $value; 
     } 

     function __construct() { 
      Model::$models[]= $this; 
     } 

     public function save() { 
      // Execute database query for saving the current Model 
     } 

     static public function update() { 
      foreach (Model::$models as $model) { 
       if ($model->changed) { 
        $model->save(); 
       } 
      } 
     } 
} 

Une solution basée sur un modèle brille vraiment quand il s'agit de créer différents types de modèles. Par exemple:

class Person extends Model { 
     public function save() { 
      // Execute person-specific write operations 
     }  
} 

class Doctor extends Person { 
     public function save() { 
      // Execute all Person write operations 
      parent::save(); 
      // Save the extra bits that belong to a doctor 
     } 
} 

$person1= new Person(); 
$person->firstname= 'Jon'; 
$person->lastname= 'Skeet'; 

$doctor1= new Doctor(); 
$doctor1->firstname= 'House'; 
$doctor1->lastname= 'MD'; 

// Save all modified models 
Model::update(); 

Bien que je trouve rarement l'utilisation pour ce genre de mécanismes de mise à jour de masse. Les conditions d'écriture sont généralement plus spécifiques.

1

Une question que vous pourriez poser à yourslef est de savoir si vous voulez réinventer la roue ou non. Les couches ORM telles que Propel ou Doctrine implémentent déjà l'objet dans le mappage de SGBD (R), vous pouvez donc consulter leurs détails d'implémentation.

Propel utilisera votre seconde approche, ils gardent même les drapeaux au niveau du champ pour créer une seule instruction de mise à jour (qui gardera l'interaction de la base de données au minimum). Vous apprendrez beaucoup si vous étudiez leur source (ou mieux encore, arrêtez de perdre votre temps et utilisez leur implémentation - vous ne le regretterez pas: p).

Questions connexes