Что такое алгоритм для ORM? - PullRequest
3 голосов
/ 29 июля 2010

Я искал ORM для использования в приложении php / mysql.Однако ни один из них не захватил мое внимание прошлыми тестами "Здравствуй, мир".Итак, я решил провести небольшое исследование и попытаться написать свой собственный ORM.Однако я не смог найти ресурсы, которые объясняют на уровне кода, как обрабатывать отношения БД.Понятие о том, как работает ORM, понятно, но когда я пытаюсь выложить его в код, я не знаю, какой подход лучше.Лучше всего построить несколько небольших запросов или создать один сложный запрос для каждого возможного сценария?Любое понимание алгоритма или архитектуры ORM приветствуется!

Ответы [ 3 ]

2 голосов
/ 08 января 2014

Хорошо, давайте сделаем некоторые рамки ORM на лету.Когда вы пометили тег php, давайте закодируем его в PHP.

Но прежде чем писать его, мы должны знать некоторые базовые понятия или некоторую базовую терминологию о предметах, связанных с orm.В этом примере у нас будет:

  1. ORM Framework - ORM Framework берет на себя ответственность позаботиться о соединениях с сервером и абстракциях соединения с сервером.(Полные платформы orm также поддерживают автоматическое сопоставление классов и таблиц.)

  2. Уровень данных - эта часть отвечает за сопоставление классов с таблицами.Например, уровень доступа к данным знает, как сохранить конкретный объект класса в фактическую таблицу и как загрузить конкретную таблицу в конкретный объект класса.(ПРИМЕЧАНИЕ. Практически любая последняя платформа ORM может избежать вас с этого уровня. Например, http://dbphp.net или Doctrine будут поддерживать каждый аспект этого слоя, а также отношения и даже автоматическое создание таблиц).

  3. Бизнес-уровень. Этот уровень содержит фактические рабочие классы. Бизнес-уровень часто обозначает модель или модель включает в себя бизнес-уровень

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

<?php
class user
{
    public $id;
    public $name
    public function __construct ($name=null)
    {
        $this->name = $name;
    }
}
?>

Как видите, ваш бизнес-уровень или модель ничего не знает о том, где и как они сохранены или загружены.Он только занимается бизнесом, связанным с проектом.В этом и заключается название слоя.

Во-вторых, давайте создадим простую структуру ORM:

<?php

//The connection link which can be changed any time
class link
{
    public $link;
    public function __construct ($hostname, $database, $username, $password)
    {
        $this->link = new \PDO ('mysql:host='.$hostname.';dbname='.$database, $username, $password);
        $this->link->query('use '.$database);
    }
    public function fetch ($query)
    {
        $result = $this->link->query($query)->fetch();
    }
    public function query ($query)
    {
        return $this->link->query($query);
    }
    public function error ()
    {
        return $this->link->errorInfo();
    }
}

//A structure which collects all link(s) and table/class handlers togather
class database
{
    public $link;
    public $tables = array ();
    public function __construct ($link)
    {
        $this->link = $link;
        table::$database = $this;
    }
}

//A basic table handler class
//In recent ORM frameworks they do all the default mappings
class table
{
    public static $database;
}
?>

Как вы заметили, наш класс таблиц в нашей среде ORM кажется очень плохим.Но если бы эта структура была сложной средой, она поддерживала бы также уровень данных и имела бы все функциональные возможности для работы с любой таблицей.

Но поскольку вам нужно знать, как работают платформы ORM в этом случае, мы сделаем обработчики уровня данных длякаждый класс в нашем бизнес-уровне.

Так что это ваш уровень данных.Он настолько информативен, что я думаю, что он не нуждается в какой-либо документации:

<?php
class users extends table
{
    public function create ($row)
    {
        $return = new user ();
        $return->id = $row[0];
        $return->name = $row[1];
        var_export($row);
        return $return;
    }
    public function load ($id=null)
    {
        if ($id==null)
        {
            $result = self::$database->link->fetch("select * from users");
            if ($result)
            {
                $return = array();
                foreach ($result as $row)
                {
                    $return[$row[0]] = $this->create($row);
                }
                return $return;
            }
        }
        else
        {
            $result = self::$database->link->fetch("select * from users where id='".$id."'");
            if ($result)
            {
                return $this->create(reset($result));
            }
            else
            {
                echo ("no result");
            }
        }
    }
    public function save ($user)
    {
        if (is_array($save))
        {
            foreach ($save as $item) $this->save ($item);
        }
        if ($user->id==null)
        {
            return self::$database->link->query("insert into users set
                                                 name='".$user->name."'");
        }
        else
        {
            return self::$database->link->query("update users set name='".$user->name."'
                                                 where id='".$user->id."'");
        }
    }
    public function delete ($user)
    {
        self::$database->link->query ("delete from users where id='".$user->id."'");
    }
}
?>
  1. Наконец, давайте инициализируем объект $ database
  2. Установим некоторые ссылки на некоторые серверы sql.
  3. Добавить обработчик класса пользователя в базу данных.
  4. Использовать его.

Вот оно в работе:

<?
$database = new database (new link('127.0.0.1', 'system_db', 'root', '1234'));
$database->tables['users'] = new users();

if (!$database->tables['users']->save (new user('Admin')))
{
    var_export($database->link->error());
}

var_export($database->tables['users']->load(2));
?>

Если вам нужно погрузитьсяв других концепциях php ORM вы можете посетить

  1. Doctrine - http://www.doctrine -project.org / - полнофункциональный комплекс php ORM framework
  2. db.php - http://dbphp.net/ - полнофункциональный, но очень простой фреймворк php ORM.
1 голос
/ 29 июля 2010

ОРМ не просты.Ваш ORM не будет ни простым, ни эффективным.Если это одно из них, то ваше приложение достаточно простое, чтобы не нуждаться в нем в первую очередь, или вы понимаете, когда проблема усугубляется и просто не используете ее.

Простое CRUD-отображение, отображающее объект в таблицуэто просто.Начните добавлять в отношения или коллекции, и все идет к горшку.Затем возникают запросы и т. Д. Сложность возрастает нелинейным, ускоряющимся образом.

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

Довольно скоро ваш проект расходуется на настройку, обслуживание и отладку внутренней ORM, а не на продвижение вашего проекта.Если бы вы потратили время на инвестирование в ORM и просто написали слой DAO с SQL, ваш проект был бы дальше, проще и эффективнее.

Честно говоря, принятие ORM достаточно сложно оправдать, в зависимости отв масштабе проекта.Написание собственного еще более вероятно, не стоит инвестиций.

1 голос
/ 29 июля 2010

Многие ORM в наши дни построены на шаблоне Active Record или его вариациях.В этой схеме вы обычно автоматически генерируете классы, которые соответствуют каждой таблице в базе данных, каждый из этих классов возвращает экземпляр себя или подкласса, который соответствует каждой строке в таблице:

Например,если у вас есть таблица Users:

$user_list = Users.getAllUsers(); //SELECT * FROM Users
//foreach row, create a new User() instance
$user_list[0].name = "Peter";
//UPDATE Users SET name = 'Peter' WHERE user_id = <$user_list[0].id>
$user_list[0].commit(); 

О реализации, лучше всего попытаться минимизировать количество запросов, отправляемых на сервер, но это не всегда тривиально и не желательно.

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