对象关系映射(Object Relational Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。

ORM提供了所有SQL语句的生成,代码人员远离了数据库概念。从一个概念需求(例如一个HQL)映射为一个SQL语句,并不需要什么代价,连1%的性能损失都没有。真正的性能损失在映射过程中,更具体地讲,是在对象实例化的过程中。

目前PHP 开源比较有名的 ORM 有以下几个:

1、Propel

Propel是一个适用于PHP5的ORM映射(Object Relational Mapping)框架,它基于Apache Torque提供对象持久层支持。它通过XML格式的模式定义文件和相应的配置文件来生成SQL和类,它允许你使用对象代替SQL来读写数据库表中的记录。Propel提供一个生成器来为你的数据模型创建SQL定义文件和PHP类。开发者也可以十分简单的定制生成的类,我们还可以通过XML, PHP类和Phing构建工具把Propel集成到已有的应用开发框架中去.例如PHP框架symfony的1.2以前的版本就是默认使用了精简版的Propel作为默认ORM框架。

官方网站:http://www.propelorm.org/

2、Doctrine

Doctrine是一个PHP的ORM框架,它必须运行在>=php5.2.3版本上,它是一个功能强大的数据抽象层。

它的一个主要特征就是使用面向对象的方式来实现数据库查询的封转,它底层通过一个类似 Hibernate HQL的DQL的查询语句进行数据库查询,这使得开发的灵活性更强,大大减小了重复代码。相比Propel,Doctrine的优点在于它支持支持全文检索,Doctrine的文档一直就比Propel要全面丰富,社区更活跃,而且使用起来更加自然、更易阅读、更接近原生SQL。性能方面也略微优于Propel。同样你也可以可以很方便的把Doctrine集成到现有的应用框架中去,比如PHP框架symfony的1.3以后的版本将Doctrine作为默认的ORM框架,同时也可以将Doctrine和Codeigniter整合起来。

官方网站: http://www.doctrine-project.org/

3、EZPDO

EZPDO是一个十分轻量级的PHP ORM框架。EZPDO的作者的本意旨在降低复杂的ORM学习曲线,尽可能在ORM的运行效率和功能之间做一个平衡点,它是我至今用过的最简单的ORM框架,我目前还想将它集成到我的CoolPHP SDK中来,而且运行效率相当不错,功能也基本能满足需求,只不过ESPDO的更新比较缓慢。

官方网站:http://www.ezpdo.net/blog/?p=2

4、RedBean

RedBean是一个易于使用,轻量级PHP ORM框架,提供对MySQL, SQLite&PostgreSQL的支持。RedBean架构非常灵活,核心也非常简约,开发者可以很方便的通过插件来扩展功能。

官方网站:http://www.redbeanphp.com/

5、其他

国内的fleaphp开发框架基于TableDataGateway实现ORM实现;Zend Framework除了提供对 SQL 语句的封装以外,也同样实现了TableGateway、TableRowSet、TableRow的实现;还有一些类似Rails的ActiveRecord实现的解决方案。

总的来说,一般ORM框架对付简单的应用系统来说都能满足基本需求,可以大大降低开发难度,提高开发效率,但是它在SQL优化方面,肯定是比纯SQL语言要差一些,对复杂关联、SQL内嵌表达式的处理可能不是很理想。也许这主要是由于PHP本身对象持久化的问题,导致ORM效率过低,普遍比纯SQL要慢。但是这些都是有办法解决的,最基本的解决性能的方案,我们可以通过缓存来提高效率,Hibernate来说,虽然配置比较繁杂,但是它通过灵活的使用二级缓存和查询缓存极大的缓解数据库的查询压力,极大的提升了系统的性能。

如果你想自己实现一个PHP的ORM,下面的可以参考下:

001 <?php
002 abstract class Model{
003    protected $pk 'id';
004    protected $_ID = null;
005    protected $_tableName;
006    protected $_arRelationMap;
007    protected $_modifyMap;
008    protected $is_load = false;
009    protected $_blForDeletion;
010    protected $_DB;
011  
012    public function __consturct($id = null){
013        $this->_DB = mysql_connect('127.0.0.1','root','') ;
014        $this->_tableName = $this->getTableName();
015        $this->_arRelationMap = $this->getRelationMap();
016        if(isset($id))$this->_ID = $id;
017    }
018    abstract protected function getTableName();
019    abstract protected function getRelationMap();
020  
021    public function Load(){
022        if(isset($this->_ID)){
023            $sql "SELECT ";
024            foreach($this->_arRelationMap as $k => $v){
025                $sql .= '`'.$k.'`,';
026            }
027            $sql .= substr($sql,0,strlen($sql)-1);
028            $sql .= "FROM ".$this->_tableName." WHERE ".$this->pk." = ".$this->_ID;
029            $result =$this->_DB->mysql_query($sql);
030            foreach($result[0] as $k1 => $v1){
031               $member $this->_arRelationMap[$key];
032               if(property_exists($this,$member)){
033                  if(is_numeric($member)){
034                      eval('$this->'.$member.' = '.$value.';');
035                  }else{
036                      eval('$this->'.$member.' = "'.$value.'";');
037                  }
038               }
039            }
040        }
041        $this->is_load = true;
042    }
043    public function __call($method,$param){
044       $type   substr($method,0,3);
045       $member substr($method,3);
046       switch($type){
047          case 'get':
048              return $this->getMember($member);
049              break;
050          case 'set':
051              return $this->setMember($member,$param[0]);
052       }
053       return false;
054    }
055    public function setMember($key){
056        if(property_exists($this,$key)){
057           if(is_numeric($val)){
058              eval('$this->'.$key.' = '.$val.';');
059           }else{
060              eval('$this->'.$key.' = "'.$val.'";');
061           }
062           $this->_modifyMap[$key] = 1;
063        }else{
064           return false;
065        }
066    }
067     
068    public function getMember($key,$val){
069        if(!$this->is_load){
070           $this->Load();
071        }
072        if(property_exists($this,$key)){
073           eval('$res = $this->'.$key.';' );
074           return $this->$key;
075        }
076        return false;
077    }
078  
079    public function save(){
080       if(isset($this->_ID)){
081           $sql "UPDATE ".$this->_tableName." SET ";
082           foreach($this->arRelationMap as $k2 => $v2){
083               if(array_key_exists$k2$this->_modifyMap)){
084                   eval'$val = $this->'.$v2.';');
085                   $sql_update .=  $v2." = ".$val;
086               }
087           }
088           $sql .= substr($sql_update,0,strlen($sql_update));
089           $sql .= 'WHERE '.$this->pk.' = '.$this->_ID;
090       }else{
091           $sql "INSERT INTO ".$this->_tableName." (";
092           foreach($this->arRelationMap as $k3 => $v3){
093               if(array_key_exists$k3,$this->_modifyMap)){
094                   eval('$val = $this->'.$v3.';');
095                   $field  .= "`".$v3."`,";
096                   $values .= $val;
097               }
098           }
099           $fields substr($field,0,strlen($field)-1);
100           $vals   substr($values,0,strlen($values)-1);
101           $sql .= $fields." ) VALUES (".$vals.")";
102       }
103       echo $sql;
104       //$this->_DB->query($sql);
105    }
106    public function __destory(){
107       if(isset($this->ID)){
108          $sql "DELETE FROM ".$this->_tableName." WHERE ".$this->pk." = ".$this->_ID;
109         // $this->_DB_query($sql);
110       }
111    }
112 }
113  
114 class User extends Model{
115     protected  function getTableName(){
116        return "test_user";
117     }
118     protected function getRelationMap(){
119         return array(
120                       'id'       => USER_ID,
121                       'user_name'=> USER_NAME,
122                       'user_age' => USER_AGE
123                     );
124     }
125     public function getDB(){
126        return $this->_DB;
127     }
128 }
129  
130 $UserIns new User();
131 print_r($UserIns);
132  
133 ?>

PHP ORM框架与简单代码实现(转)的更多相关文章

  1. 【Idea插件】kotlin的orm框架一键生成代码框架

    @font-face { font-family: octicons-link; src: url("data:font/woff;charset=utf-8;base64,d09GRgAB ...

  2. .net ORM框架(Dapper简单应用)

    1.引入 Dapper.dll类库 2.创建书籍模型book using System; using System.Collections.Generic; using System.Linq; us ...

  3. ent facebook 开源的golang orm 框架

    ent 是facebook 开源的golang orm 框架,简单强大,具有提下特性 schema 即代码 方便的图遍历 静态类型以及显示api 多种存储引擎支持(当前是mysql,sqlite,以及 ...

  4. Android orm 框架xUtils简介

    数据库操作建议用ORM框架,简单高效.这里推荐xUtils,里面包含DBUtils.github地址:https://github.com/wyouflf/xUtils 获得数据库实例建议用单例模式. ...

  5. 一行代码调用实现带字段选取+条件判断+排序+分页功能的增强ORM框架

    问题:3行代码 PDF.NET是一个开源的数据开发框架,它的特点是简单.轻量.快速,易上手,而且是一个注释完善的国产开发框架,受到不少朋友的欢迎,也在我们公司的项目中多次使用.但是,PDF.NET比起 ...

  6. 简单实用的Android ORM框架TigerDB

    TigerDB是一个简单的Android ORM框架,它能让你一句话实现数据库的增删改查,同时支持实体对象的持久化和自动映射,同时你也不必关心表结构的变化,因为它会自动检测新增字段来更新你的表结构. ...

  7. 封装JDBC:实现简单ORM框架lfdb

    作者:Vinkn 来自http://www.cnblogs.com/Vinkn/ 一.简介 框架就是一组可重用的构件,LZ自己写的姑且就叫微型小框架:lfdb.LZ也对其他的ORM框架没有什么了解,现 ...

  8. ASP.NET MVC 使用 Petapoco 微型ORM框架+NpgSql驱动连接 PostgreSQL数据库

    前段时间在园子里看到了小蝶惊鸿 发布的有关绿色版的Linux.NET——“Jws.Mono”.由于我对.Net程序跑在Linux上非常感兴趣,自己也看了一些有关mono的资料,但是一直没有时间抽出时间 ...

  9. 最好的5个Android ORM框架

    在开发Android应用时,保存数据有这么几个方式, 一个是本地保存,一个是放在后台(提供API接口),还有一个是放在开放云服务上(如 SyncAdapter 会是一个不错的选择). 对于第一种方式, ...

随机推荐

  1. Idea中运行Testng时,报SAXParseException:parallel为none的问题原因及解决

    今天更新了testng的版本为6.9.10, 在idea中运行测试案例时,报错如下: org.testng.TestNGException: org.xml.sax.SAXParseException ...

  2. Bootstrap_Javascript_图片轮播

    一 . 结构分析 一个轮播图片主要包括三个部分: ☑ 轮播的图片 ☑ 轮播图片的计数器 ☑ 轮播图片的控制器 第一步:设计轮播图片的容器.在 Bootstrap 框架中采用 carousel 样式,并 ...

  3. Bootstrap_表单_图像

    在Bootstrap框架中对于图像的样式风格提供以下几种风格: 1.img-responsive:响应式图片,主要针对于响应式设计2.img-rounded:圆角图片3.img-circle:圆形图片 ...

  4. Linux操作:

    1.在Linux中第一个字符代表这个文件是目录.文件或链接文件等等. 当为[ d ]则是目录,当为[ - ]则是文件,若是[ l ]则表示为链接文档(link file),若是[ b ]则表示为装置文 ...

  5. JS判断是否为一个数组

    function isArray(object){ return object && typeof object==='object' && Array == obje ...

  6. Python Tutorial 学习(五)--Data Structures

    5. Data Structures 这一章来说说Python的数据结构 5.1. More on Lists 之前的文字里面简单的介绍了一些基本的东西,其中就涉及到了list的一点点的使用.当然,它 ...

  7. ha666_go运行环境配置

    项目地址:http://git.oschina.net/ha666/ha666_go 服务器配置: CPU: 1核 内存: 1024 MB 操作系统: CentOS 7.0 64位 内网IP: 10. ...

  8. [BZOJ 3209] 花神的数论题 【数位统计】

    题目链接: BZOJ - 3209 题目大意 设 f(x) 为 x 的二进制表示中 1 的个数.给定 n ,求 ∏ f(i)     (1 <= i <= n) . 题目分析 总体思路是枚 ...

  9. WPAD 的原理及实现

    WPAD 通过让浏览器自动发现代理服务器,使代理服务器对用户来说是透明的,进而轻松访问互联网.WPAD 可以借助 DNS 服务器或 DHCP 服务器来查询代理自动配置(PAC)文件的位置. 引言 代理 ...

  10. 【Java】详解Java解析XML的四种方法

    XML现在已经成为一种通用的数据交换格式,平台的无关性使得很多场合都需要用到XML.本文将详细介绍用Java解析XML的四种方法. AD: XML现在已经成为一种通用的数据交换格式,它的平台无关性,语 ...