ORM:object relation mapping,即對象關系映射,簡單的說就是對象模型和關系模型的一種映射。為什么要有這么一個映射?很簡單,因為現在的開發語言基本都是oop的,但是傳統的數據庫卻是關系型的。為了可以靠貼近面向對象開發,我們想要像操作對象一樣操作數據庫。 舉個例子:獲取一篇文章,傳統的方式先要執行一個sql檢索數據
select * from post where id = 1
然后輸出標題和內容使用
echo $post['title']; echo $post['content'];
上面的代碼遇到面向對象強迫症者,他們會糾結死的。 所以他們想出了這個東西,在ORM里獲取一篇文章可以這樣:
$post = postTable::getInstance()->find(1);#會再內部執行select * from post where id = 1
然后輸出:
echo $post->getTitle(); echo $post->getContent();
媽媽再也不用擔心我的強迫症了^_^
高級點的應用,文章和分類是一對多關系、文章和標簽是多對多關系
$cate = $post->getCategory(); //獲取文章分類 echo $cate->getName(); //獲取分類名 $tags = $post->getTags(); //獲取一個文章的所有標簽
是不是一個sql都沒寫就獲取到我們需要的所有數據了?使用ORM可以完全不寫sql而實現應用,這些ORM都替我們做了。除此之外,orm還可以隔離底層數據庫層,我們不需要關心我們使用的是mysql還是其他的關系型數據庫。
我知道的orm: doctrine和propel 除了orm之外還有odm,即object document mapping,對象文檔映射,使用文檔數據庫比如mongodb時使用
對象關系映射(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來說,雖然配置比較繁雜,但是它通過靈活的使用二級緩存和查詢緩存極大的緩解數據庫的查詢壓力,極大的提升了系統的性能。
http://www.gajotres.net/best-available-php-orm-libraries-part-1/
https://github.com/catfan/Medoo
ORM即Object/Relation Mapping的簡寫,一般稱作“對象關系映射”,在Web開發中最常出沒於和關系型數據庫交互的地方。接口、中間件、庫、包,你都可以這么稱呼它。
我們可以結合PHP和MySQL,從ORM的四個核心理念來認識它:
- 簡單:ORM以最基本的形式建模數據。比如ORM會將MySQL的一張表映射成一個PHP類(模型),表的字段就是這個類的成員變量
- 精確:ORM使所有的MySQL數據表都按照統一的標准精確地映射成PHP類,使系統在代碼層面保持准確統一
- 易懂:ORM使數據庫結構文檔化。比如MySQL數據庫就被ORM轉換為了PHP程序員可以讀懂的PHP類,PHP程序員可以只把注意力放在他擅長的PHP層面(當然能夠熟練掌握MySQL更好)
- 易用:ORM的避免了不規范、冗余、風格不統一的SQL語句,可以避免很多人為Bug,方便編碼風格的統一和后期維護
接下來再通過一個很基本的例子來說明一下ORM的使用,還以PHP和MySQL為例。
user這個數據模型是再普遍不過的了。假設我們有一張user數據表,結構如圖:
在OOP中通常我們需要寫一個對應的class User來作為user數據表的數據模型:
// 聲明class User class User{ $id; $name; function create(){/*...*/} function load($id){/*...*/} } // 使用class User $user = new User(); $user->name = 'fancy'; $user->create();
但是通過ORM,我們可以不用去聲明class User,可以直接繼承ORM提供的工廠類,比如:
// 直接使用!對於熟悉MVC的親知道這個意義之所在! $user = new ORM('user'); // ORM都有自己的規則,這里直接使用了MySQL的表名 $user->name = 'fancy'; // MySQL的表的字段就是$user對象的成員變量 $user->save(); // 掉用ORM提供的接口函數
ORM一般都針對數據模型提供了一下常見的接口函數,比如:create(), update(), save(), load(), find(), find_all(), where()等,也就是講sql查詢全部封裝成了編程語言中的函數,通過函數的鏈式組合生成最終的SQL語句。
所以由這些來看,ORM對於敏捷開發和團隊合作開發來說,好處是非常非常大的。這里就羅列一下我想到的ORM顯著的優點:
- 大大縮短了程序員的編碼時間,減少甚至免除了對Model的編碼
- 良好的數據庫操作接口,使編碼難度降低,使團隊成員的代碼變得簡潔易讀、風格統一
- 動態的數據表映射,在數據表結構甚至數據庫發生改變時,減少了相應的代碼修改
- 減少了程序員對數據庫的學習成本
- 可以很方便地引入數據緩存之類的附加功能
但是ORM並不是一個完美的東西,它同時也有其自身不可避免的缺點:
- 自動化進行關系數據庫的映射需要消耗系統性能。其實這里的性能消耗還好啦,一般來說都可以忽略之,特別是有cacha存在的時候
- 在處理多表聯查、where條件復雜之類的查詢時,ORM的語法會變得復雜且猥瑣
- 越是功能強大的ORM越是消耗內存,因為一個ORM Object會帶有很多成員變量和成員函數。有一次修復bug時就遇見,使用ORM查詢的時候會占用12MB的內存,而使用SQL的查詢時只占用了1.7MB……
ORM就是這么一個讓人又愛又恨的東西。回到我們開始的問題:“ORM到底是用還是不用?”。
Fancy個人的觀點是:ORM要用!但關鍵部位不能用!
因為對於一般的Web應用開發來說,使用ORM確實能帶來上述的諸多好處,而且在大部分情況下涉及不到ORM的不好的地方。但是在系統里面有大數據量、大運算量、復雜查詢的地方,就不要用ORM。ORM的性能問題將給你帶來災難。在這些地方就可以使用純SQL或者其他簡單輕量的DB Helper庫了。在詳細了解ORM之后,你就可以揚長避短讓ORM發揮其最大效用了。