DataMapper, модель - PullRequest
       16

DataMapper, модель

0 голосов
/ 12 декабря 2011

У меня есть вопрос о классах ' моделирование, обучение ', есть два простых правила, которые не вписываются в мою голову, и что такое обучение должно обеспечить,

в моей модели, будь то 'CustomersModel, VehicleModel' 'я' имею 'иметь доступ к методам записи запросов (SQLBuilder), но также иметь доступ к базе данных, которая не будет устанавливать маппер, так как маппер работает на скамейке, а не на банке над маппером, немного усложненный моей ситуацией.

Представьте себе следующее:

<?php
   // database access, mapping
   abstract class Mapper { }
   abstract class Model { } 


   interface Connection { } // to recognize it's a database access 
   class MySQL implements Connection { }
   class PgSQL implements Connection { } 

    // SQL Helper, some methods to write a update, insert, delete, select query
   class SQLBuilder { }

   // my custom models
   class Customers extends Model { }

визуализируя эту структуру, «Клиенты», уже имеет доступ к мапперу, и в этом случае у меня будет свойство «$_table» (среди прочего) в таблице «Клиенты», чтобы признать, что эта модель работает, но .. У меня нет доступа к средству записи запросов, а не к базе данных, для этого я подумал о методе 'main()', где setaria подключается к базе данных, используя 'setDatabaseConnection ( Connection $connection )', но код будет часто повторяется, просто представьте, что для N моделей все используют -> setDatabaseConnectiom, и все приложение использует только одну базу данных? ..

Мой вопрос в основном таков: предоставить доступ к базе данных без использования метода сеттера в модели (Customers, Vehicle) и сразу же создавать запросы.

Я не хочу использовать это ..

<?php

       // my models
       class Customers extends Model { 

              // method of mapper does'nt implement
              public function getByCity ( $city ) {
                     $query = $this->select()->from($this->_table)->where('city = ?', $city);
                     $resultSet = $this->getConnection()->query( $query );
                     if ( $resultSet->rowCount() > 1 ) {
                            return $resultSet->fetchAll();
                     } else return $resultSet->fetch();
              }

       }

так как я могу использовать save (), delete (), update () маппер. в этом случае метод getConnection () должен получить соединение по умолчанию и вернуть класс.

Ответы [ 2 ]

2 голосов
/ 15 декабря 2011

Если ваши модели "должны иметь" доступ к базе данных напрямую (через SQLBuilder), вы используете неправильный шаблон: Data Mapper . A Data Mapper обычно выполняет SQL, поэтому он предназначен для:

[Models]----[Mapper]----[Storage]

В вашем примере выглядит так, что мапперы где-то торчат, но неясно, какими они являются, поскольку вашим моделям необходим прямой доступ к хранилищу:

[Models]---------[Storage]
   `-----[Mapper]---´

Я предлагаю вам внедрить Data Mapper как схему в P Книги EAA & shy; Teaser , которая поставляется с примерами кода и обсуждением, как решить больше сложное взаимодействие SQL в типах мапперов и супертипах.

В качестве альтернативы Active Record с некоторыми общими расширениями для модели или некоторыми шлюзами данных строк или Шлюз табличных данных может также подойти для ваших нужд.

1 голос
/ 15 декабря 2011

Есть несколько способов справиться с этим.У вас может быть фабричный класс, который будет создавать экземпляр вашего класса Model.Что-то в строке:

class ModelLoader {

    public function load($name)
    {
        $class = new $name();
        $class->setConnection(/* set connection class */);
        return $name;
    }
}

$loader = new ModelLoader();
$customer = $loader->load('Customer');

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

interface Connection {}
class MySQL implements Connection {}
class PgSQL implements Connection {}

abstract class Model {

    private $connection = null;

    private static $defaultConnection;

    public function setConnection(Connection $connection = null)
    {
        if ($connection === null) {
            if (!self::$defaultConnection instanceof Connection) {
                throw new Exception('Default connection missing.');
            }
            $connection = self::$defaultConnection;
        }
        $this->connection = $connection;

        return $this;
    }

    public function getConnection()
    {
        if ($this->connection === null) {
            $this->setConnection();
        }
        return $this->connection;
    }

    public static function setDefaultConnection(Connection $connection)
    {
        self::$defaultConnection = $connection;
    }
}

class Customers extends Model { }
class Vehicle extends Model { }


Model::setDefaultConnection(new MySQL);

$customer = new Customers();
$customer->getConnection();

$vehicle = new Vehicle();
$vehicle->setConnection(new PgSQL);

echo '<pre>';
var_dump($customer);
var_dump($vehicle);

// output
object(Customers)#2 (1) {
  ["connection":"Model":private]=>
  object(MySQL)#1 (0) {
  }
}
object(Vehicle)#3 (1) {
  ["connection":"Model":private]=>
  object(PgSQL)#4 (0) {
  }
}

Надеюсь, что этопомогает

...