Обновление данных через объекты - PullRequest
1 голос
/ 26 марта 2010

Итак, допустим, у меня есть запись:

$record = new Record();

и скажем, я назначил некоторые данные для этой записи:

$record->setName("SomeBobJoePerson");

Как мне получить это в базе данных. Должен ли я .....

A) Пусть модуль сделает это.

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

B) Запускать модули в конце скрипта

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
    }


 }

Ответы [ 3 ]

1 голос
/ 26 марта 2010

Вопрос, который вы могли бы задать себе, - хотите ли вы изобретать велосипед или нет. Слои ORM, такие как Propel или Doctrine , уже реализуют отображение объектов в (R) СУБД, поэтому вы можете посмотреть подробности их реализации.

Propel будет использовать ваш второй подход, они даже сохраняют флаги на уровне поля, чтобы создать только один оператор обновления (который будет поддерживать взаимодействие с базой данных как минимум). Вы многому научитесь, если изучите их источник (или, еще лучше, перестанете тратить время и будете использовать их реализацию - вы не пожалеете об этом: p).

0 голосов
/ 26 марта 2010

Пример A обновляет базу данных всякий раз, когда вызывается setName. Эта функция выглядит как простой метод записи, но при вызове выполняет дорогостоящие действия (подключение к базе данных, выполнение запроса и т. Д.). Эти непреднамеренные эффекты сайта делают Пример B более привлекательным.

В качестве дополнительного примера: позже вам может понадобиться класс Validator, который проверяет запись и гарантирует, что запись находится в допустимом состоянии. Но для того, чтобы изучить запись, вы должны сначала определить ее, задав имя - чтобы запись сохранялась до того, как вы сможете проверить ее состояние. Определение состояния объекта не совпадает с постоянным состоянием объекта.

Подход модели данных может работать лучше, чем подход, основанный на записях. Например:

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();
                }
            }
        }
}

Основанное на модели решение действительно хорошо подходит для создания различных типов моделей. Например:

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();

Хотя я редко нахожу применение для таких механизмов массового обновления. Условия записи обычно более конкретны.

0 голосов
/ 26 марта 2010

Это зависит от того, как вы планируете реализовать ... Выполнять все записи в одной точке (в конце запроса) приятно, потому что это позволяет оптимизировать ваши операции, консолидируя запросы там, где это возможно. Но для этого вам нужно создать что-то похожее на UnitOfWork, чтобы отслеживать, что удалить / обновить / вставить, что может открыть целую другую банку червей.

С другой стороны, если вы делаете это напрямую, когда вызываете метод персистентности для сущности, вам не нужно беспокоиться об этом.

Хотя оба подхода означают, что у вас должен быть какой-то способ убедиться, что у вас всегда есть текущие данные в вашем объекте, но работа, требуемая для реализации, варьируется по сложности в зависимости от выбранного вами подхода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...