用于学习实现基本ORM的提示/资源/模式 [英] Tips/resources/patterns for learning to implement a basic ORM

查看:136
本文介绍了用于学习实现基本ORM的提示/资源/模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看过各种MVC框架以及PHP的独立ORM框架,以及这里的其他ORM问题;然而,大多数问题要求开始使用现有的框架,这是不是我正在寻找。 (我也阅读了这个SO问题,但我' )



相反,我想我会学到最好的方法是让我的手变脏,实际上写我自己的ORM ,甚至一个简单的。除非我真的不知道如何开始,特别是因为我在其他ORM中看到的代码是如此复杂。



用我的 PHP 5.2.x这很重要) MVC框架我有一个基本的自定义数据库抽象层,它具有:




  • 非常简单的方法,如 connect($ host,$ user,$ pass,$ base)查询($ sql,$ tied) / li>
  • 它支持的每个DBMS的子类

  • 表示SQL结果集的类(和相应的子类)



    • 具有:




      • 活动记录功能,我假设是一个ORM的东西(如果我错了,请更正我)



      EDIT:澄清,我只有一个数据库抽象层。我还没有模型,但是当我实现它们时,我想他们是原生的ORM模型(可以这么说),因此这个问题。



      对我有用[0]丢个板砖[0]引用举报我来说两句(0)



      仍然,我想要一些简单的提示,从任何人谁或多或少与ORM的争吵构架。

      解决方案

      p>因为这个问题比较老,我想你已经有你的尝试,自己写一个ORM。尽管如此,当我两年前写一个自定义ORM时,我仍然想分享我的经验和想法。



      如前所述,我实施了一个自定义ORM两年前,甚至使用它在中小型项目取得一些成功。我把它集成在一个相当流行的CMS,那时(甚至现在)缺乏这样的ORM功能。此外,当时流行的框架如Doctrine没有真正说服我。自那时起,很多事情发生了变化, Doctrine 2 在一个坚实的框架中演变,因此,如果我现在有选择实现我自己的ORM或使用像Doctrine 2之类的流行框架用于生产使用,这将是没有问题 - 使用现有的,稳定的解决方案。但是:实现这样一个框架(以简单的方式)是一个非常有价值的学习练习,它帮助我在处理更大的开源ORM,当你更好地了解与对象关系映射相关的陷阱和困难。



      实现基本的ORM功能并不是太难,但是一旦对象之间的关系映射发挥作用,就会变得更加困难/有趣。 / p>



      我是如何开始的?



      什么让我挂钩的是Martin Fowlers的书企业应用程序架构的模式。如果你想编写自己的ORM,或者你只是在使用一些ORM框架,买这本书。这是最宝贵的资源之一,涵盖了许多基本和高级技术字段对象关系映射。



      基本架构



      我决定是否要使用 Active Record 方法,或某种类型的数据映射器。该决定影响如何将来自数据库的数据映射到实体。我决定实现一个简单的数据映射器,方法与 Doctrine 2 Hibernate 在Java中使用。 Active Record是ORM功能(如果您可以调用)的方法,位于 Zend Framework 。活动记录比数据映射器简单得多,但也更有限。阅读这些模式并检查提到的框架,你得到的差异相当快。如果您决定使用数据映射程序,则还应阅读 PHPs反射API 。 p>

      查询



      我有一个雄心勃勃的目标来创建我自己的查询语言, DQL 在教义或 Hibernate中的HQL 。我很快就沮丧了,因为编写一个自定义的SQL解析器/ lexer似乎是复杂的(它真的是!)。我所做的是实施查询对象,以便封装涉及的表的信息在查询中(这很重要,因为您需要将数据从数据库映射到每个表的相关类)。



      在我的ORM中查询对象看起来像这样:

        public function findCountryByUid($ countryUid){
      $ queryObject = new QueryObject
      $ queryObject-> addSelectFields(new SelectFields('countries','*'))
      - > addTable(new tables('countries'))
      - > addWhere countries.uid ='。intval($ countryUid)。'');

      $ res = $ this-> findByQuery($ queryObject);
      return $ res-> getSingleResult();
      }

      配置



      通常,你还需要一些配置格式,Hibernate使用XML(其他),Doctrine 2使用PHP注释,EZComponents在它的 Persistent Object组件作为配置格式。这也是我使用的,它似乎是一个自然的选择,我使用的CMS也使用PHP配置格式。



      使用该配置,您可以定义




      • 哪个表映射到哪个类

      • 应将哪些字段映射到类实例

      • 表格的字段类型(int,string等)

      • 实体之间的关系(例如,User类具有对UserGroup类的引用)

      • 等。



      这是您在Data Mapper中用于将数据库结果映射到对象的信息。



      / strong>



      我决定采用强大的测试驱动方法,因为编写自定义ORM的复杂性。 TDD不是,写许多,很多单元测试是一个真正好的主意,在这样的项目。除此之外:让你的手脏,并保持福勒书书。 ;-)






      正如我所说的,这是值得的,但我不想再做,很大程度上是因为现在存在的成熟框架。



      我没有使用我的ORM,它工作,但缺乏许多功能,其中包括:延迟加载,组件映射,事务支持,缓存,自定义类型,准备语句/参数等。它的性能在大规模项目中使用不够好。



      不过,我希望我能给你一些起点ORM的领域,如果你不知道他们已经。 ; - )


      I've seen various MVC frameworks as well as standalone ORM frameworks for PHP, as well as other ORM questions here; however, most of the questions ask for existing frameworks to get started with, which is not what I'm looking for. (I have also read this SO question, but I'm not sure what to make of it as the answers are vague.)

      Instead, I figured I'd learn best by getting my hands dirty and actually writing my own ORM, even a simple one. Except I don't really know how to get started, especially since the code I see in other ORMs is so complicated.

      With my PHP 5.2.x (this is important) MVC framework I have a basic custom database abstraction layer, that has:

      • Very simple methods like connect($host, $user, $pass, $base), query($sql, $binds), etc
      • Subclasses for each DBMS that it supports
      • A class (and respective subclasses) to represent SQL result sets

      But does not have:

      • Active Record functionality, which I assume is an ORM thing (correct me if I'm wrong)

      EDIT: to clarify, I only have a database abstraction layer. I don't have models yet, but when I implement them I want them to be native ORM models (so to speak), hence this question.

      I've read up a little about ORM, and from my understanding they provide a means to further abstract data models from the database itself by representing data as nothing more than PHP-based classes/objects; again, correct me if I am wrong or have missed out in any way.

      Still, I'd like some simple tips from anyone else who's dabbled more or less with ORM frameworks. Is there anything else I need to take note of, simple, academic samples for me to refer to, or resources I can read?

      解决方案

      As this question is rather old, I guess you already have had your try at writing an ORM yourself. Nonetheless, as I wrote a custom ORM two years ago, I would still like to share my experience and ideas.

      As said I implemented a custom ORM two years ago and even used it with some success in small to medium sized projects. I integrated it in a rather popular CMS which at that time (and even now) lacks such ORM functionality. Furthermore, back then, popular frameworks like Doctrine didn´t really convince me. Much has changed since then and Doctrine 2 evolved in a solid framework, so, if I now had the choice between implementing my own ORM or using one of the popular frameworks like Doctrine 2 for production use, this would be no question at all - use the existing, stable solutions. BUT: implementing such a framework (in a simple manner) was a very valuable learning exercise and it helped me a lot in working with larger open source ORMs, as you get a better understanding for the pitfalls and difficulties associated with object relational mapping.

      It is not too difficult to implement basic ORM functionality, but as soon as mapping of relationships between objects come into play, it gets much, much more difficult/interesting.


      How did I get started?

      What got me hooked was Martin Fowlers book Patterns of Enterprise Application Architecture. If you want to program your own ORM or even if you are just working with some ORM framework, buy this book. It is one of the most valuable resources that cover many of the basic and advanced techniques regarding the field of object relational mapping. Read up on it, you get many great ideas on the patterns behind a ORM.

      Basic Architecture

      I decided if I would like to use rather an Active Record approach or some kind of Data Mapper. This decision influences on how the data from the database is mapped to the entity. I decided to implement a simple Data Mapper, the same approach as Doctrine 2 or Hibernate in Java uses. Active Record is the approach of the ORM functionality (if you can call it so) in Zend Framework. Active Record is much simpler then a Data Mapper, but also much more limited. Read up on these patterns and check the mentioned frameworks, you get the difference pretty fast. If you decide to go with a Data Mapper, you should also read up on PHPs reflection API.

      Querying

      I had the ambitious goal to create my own query language, much like DQL in Doctrine or HQL in Hibernate. I soon abondoned that, as writing a custom SQL parser/lexer seemed way to complicated (and it really is!). What I did was to implement a Query Object, in order to encapsulate the information which table is involved in the query (thats important as you need to map the data from the database to the relevant classes for each table).

      Querying for an object in my ORM looked like this:

      public function findCountryByUid($countryUid) {
          $queryObject = new QueryObject();
          $queryObject->addSelectFields(new SelectFields('countries', '*'))
                  ->addTable(new Table('countries'))
                  ->addWhere('countries.uid = "' . intval($countryUid) . '"');
      
          $res = $this->findByQuery($queryObject);
          return $res->getSingleResult();
      }
      

      Configuration

      Normally, you also need to have some kind of configuration format, Hibernate uses XML (among others), Doctrine 2 uses PHP annotations, EZComponents uses PHP arrays in its Persistent Object component as config format. Thats what I used, too, it seemed like a natural choice and the CMS I worked with used the PHP configuration format, too.

      With that configuration, you define

      • which table gets mapped to which class
      • what fields should get mapped to the class instance
      • what type the fields of the table have (int, string, etc.)
      • the relations between the entities (e. g. a User class has a reference to a UserGroup class)
      • etc.

      And thats the information you use in your Data Mapper to map the DB result to objects.

      Implementation

      I decided to go with a strong test driven approach, because of the complex nature of writing a custom ORM. TDD or not, writing many, many unit tests is a really good idea on such a project. Apart from that: get your hands dirty and keep Fowlers book close. ;-)


      As I said it was really worth the effort, but I wouldn´t want to do it again, much because of the mature frameworks that exist nowadays.

      I don´t use my ORM anymore, it worked, but lacked many features, among others: lazy loading, component mapping, transaction support, caching, custom types, prepared statements/parameters etc. And it´s performance wasn´t good enough for using it in large scale projects.

      Nonetheless, I hope I could give you some starting points in the field of ORM, if you didn´t knew them already. ;-)

      这篇关于用于学习实现基本ORM的提示/资源/模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆