ORM的算法是什么?

时间:2010-07-28 21:50:53

标签: php mysql orm

我一直在寻找在php / mysql应用程序中使用的ORM。然而,没有人在“hello world”测试中引起我的注意。所以,我决定做一些研究,并尝试编写自己的自定义ORM。但是,我无法找到在代码级别解释如何处理数据库关系的资源。 ORM如何工作的概念很明确,但是当试图在代码中进行布局时,我不知道最好的方法是什么。是否最好构建几个小查询或为每个可能的场景构建一个复杂的查询?欢迎任何有关ORM算法或架构的见解!

3 个答案:

答案 0 :(得分:2)

让我们动态制作一些ORM框架。当你标记php标签时,让我们用PHP编写它。

但在我们编写之前,我们必须了解一些基本概念或一些基本术语 关于orm相关主题。在这个例子中,我们将:

  1. ORM框架 - ORM框架负责处理服务器连接和服务器连接抽象。 (完整的orm框架也支持自动类到表的映射)。

  2. 数据层 - 此部分负责将类映射到表。 例如,数据访问层知道如何将特定类对象保存到实际表以及如何将特定表加载到特定类对象。 (注意:几乎任何最近的ORM框架都可以避开这一层。例如http://dbphp.net或Doctrine将支持该层的各个方面以及关系甚至自动表生成。

  3. 业务层 - 此层包含您的实际工作类业务层通常代表模型或模型包含业务层

  4. 让我们从业务层或模型开始我们的示例。我们非常简单的保存和加载用户的项目将有一个类业务层:

    <?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 object
    2. 建立一些sql server链接。
    3. 将用户类处理程序添加到数据库。
    4. 使用它。
    5. 这是在工作中:

      <?
      $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框架
      2. db.php - http://dbphp.net/ - 功能齐全但非常简单的php ORM框架。

答案 1 :(得分:1)

这些天的许多ORM是围绕Active Record pattern或其变体构建的。在此方案中,您通常自动生成与数据库中的每个表对应的类,每个类都返回自己的实例或与表中每行对应的子类:

例如,如果您有一个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(); 

关于实现,最好尽量减少发送到服务器的查询量,但这并不总是微不足道。

答案 2 :(得分:1)

ORM并不简单。您的ORM既不简单也不高效。如果它是其中之一,那么你的应用程序很简单,一开始就不需要一个,或者当问题变得困难并且根本就不使用它时你正在试探。

简单的CRUD将对象映射到表格很容易。开始添加关系或集合,一切都进入底池。然后是查询等。复杂性以非线性,加速的方式增加。

然后,不可避免地需要缓存以使其执行,这为项目增添了更多的乐趣和兴奋。

很快你的项目就会用于调整,维护和调试内部ORM,而不是推进你的项目。如果您花时间投入ORM并简单地用SQL编写DAO层,那么您的项目将更加简单,更加高效。

坦率地说,根据项目规模,采用ORM很难证明其合理性。写自己的东西更有可能不值得投资。