ORM是什么?
ORM文字概念
ORM代碼實(shí)現(xiàn)
?
?
一、ORM簡(jiǎn)介?
??????? 對(duì)象關(guān)系映射(Object Relational Mapping,簡(jiǎn)稱ORM)模式是一種為了解決面向?qū)ο笈c關(guān)系數(shù)據(jù)庫(kù)存在的互不匹配的現(xiàn)象的技術(shù)。簡(jiǎn)單的說(shuō),ORM是通過(guò)使用描述對(duì)象和數(shù)據(jù)庫(kù)之間映射的元數(shù)據(jù),將程序中的對(duì)象自動(dòng)持久化到關(guān)系數(shù)據(jù)庫(kù)中。那么,到底如何實(shí)現(xiàn)持久化呢?一種簡(jiǎn)單的方案是采用硬編碼方式,為每一種可能的數(shù)據(jù)庫(kù)訪問(wèn)操作提供單獨(dú)的方法。?
??????? 這種方案存在以下不足:?
??????? 1.持久化層缺乏彈性。一旦出現(xiàn)業(yè)務(wù)需求的變更,就必須修改持久化層的接口?
??????? 2.持久化層同時(shí)與域模型與關(guān)系數(shù)據(jù)庫(kù)模型綁定,不管域模型還是關(guān)系數(shù)據(jù)庫(kù)模型發(fā)生變化,毒藥修改持久化曾的相關(guān)程序代碼,增加了軟件的維護(hù)難度。?
??????? ORM提供了實(shí)現(xiàn)持久化層的另一種模式,它采用映射元數(shù)據(jù)來(lái)描述對(duì)象關(guān)系的映射,使得ORM中間件能在任何一個(gè)應(yīng)用的業(yè)務(wù)邏輯層和數(shù)據(jù)庫(kù)層之間充當(dāng)橋梁。Java典型的ORM中間件有:Hibernate,ibatis,speedframework。?
??????? ORM的方法論基于三個(gè)核心原則:?
· 簡(jiǎn)單:以最基本的形式建模數(shù)據(jù)。?
· 傳達(dá)性:數(shù)據(jù)庫(kù)結(jié)構(gòu)被任何人都能理解的語(yǔ)言文檔化。?
· 精確性:基于數(shù)據(jù)模型創(chuàng)建正確標(biāo)準(zhǔn)化了的結(jié)構(gòu)。?
二、ORM的概念?
??????? 讓我們從O/R開(kāi)始。字母O起源于"對(duì)象"(Object),而R則來(lái)自于"關(guān)系"(Relational)。幾乎所有的程序里面,都存在對(duì)象和關(guān)系數(shù)據(jù)庫(kù)。在業(yè)務(wù)邏輯層和用戶界面層中,我們是面向?qū)ο蟮摹.?dāng)對(duì)象信息發(fā)生變化的時(shí)候,我們需要把對(duì)象的信息保存在關(guān)系數(shù)據(jù)庫(kù)中。?
??????? 當(dāng)你開(kāi)發(fā)一個(gè)應(yīng)用程序的時(shí)候(不使用O/R Mapping),你可能會(huì)寫(xiě)不少數(shù)據(jù)訪問(wèn)層的代碼,用來(lái)從數(shù)據(jù)庫(kù)保存,刪除,讀取對(duì)象信息,等等。你在DAL中寫(xiě)了很多的方法來(lái)讀取對(duì)象數(shù)據(jù),改變狀態(tài)對(duì)象等等任務(wù)。而這些代碼寫(xiě)起來(lái)總是重復(fù)的。?
??????? ORM解決的主要問(wèn)題是對(duì)象關(guān)系的映射。域模型和關(guān)系模型分別是建立在概念模型的基礎(chǔ)上的。域模型是面向?qū)ο蟮?#xff0c;而關(guān)系模型是面向關(guān)系的。一般情況下,一個(gè)持久化類(lèi)和一個(gè)表對(duì)應(yīng),類(lèi)的每個(gè)實(shí)例對(duì)應(yīng)表中的一條記錄,類(lèi)的每個(gè)屬性對(duì)應(yīng)表的每個(gè)字段。?
??????? ORM技術(shù)特點(diǎn):?
??????? 1.提高了開(kāi)發(fā)效率。由于ORM可以自動(dòng)對(duì)Entity對(duì)象與數(shù)據(jù)庫(kù)中的Table進(jìn)行字段與屬性的映射,所以我們實(shí)際可能已經(jīng)不需要一個(gè)專用的、龐大的數(shù)據(jù)訪問(wèn)層。?
??????? 2.ORM提供了對(duì)數(shù)據(jù)庫(kù)的映射,不用sql直接編碼,能夠像操作對(duì)象一樣從數(shù)據(jù)庫(kù)獲取數(shù)據(jù)。?
三、ORM的優(yōu)缺點(diǎn)?
??????? ORM的缺點(diǎn)是會(huì)犧牲程序的執(zhí)行效率和會(huì)固定思維模式。?
??????? 從系統(tǒng)結(jié)構(gòu)上來(lái)看,采用ORM的系統(tǒng)一般都是多層系統(tǒng),系統(tǒng)的層次多了,效率就會(huì)降低。ORM是一種完全的面向?qū)ο蟮淖龇?#xff0c;而面向?qū)ο蟮淖龇ㄒ矔?huì)對(duì)性能產(chǎn)生一定的影響。?
??????? 在我們開(kāi)發(fā)系統(tǒng)時(shí),一般都有性能問(wèn)題。性能問(wèn)題主要產(chǎn)生在算法不正確和與數(shù)據(jù)庫(kù)不正確的使用上。ORM所生成的代碼一般不太可能寫(xiě)出很高效的算法,在數(shù)據(jù)庫(kù)應(yīng)用上更有可能會(huì)被誤用,主要體現(xiàn)在對(duì)持久對(duì)象的提取和和數(shù)據(jù)的加工處理上,如果用上了ORM,程序員很有可能將全部的數(shù)據(jù)提取到內(nèi)存對(duì)象中,然后再進(jìn)行過(guò)濾和加工處理,這樣就容易產(chǎn)生性能問(wèn)題。?
??????? 在對(duì)對(duì)象做持久化時(shí),ORM一般會(huì)持久化所有的屬性,有時(shí),這是不希望的。?
??????? 但ORM是一種工具,工具確實(shí)能解決一些重復(fù),簡(jiǎn)單的勞動(dòng)。這是不可否認(rèn)的。但我們不能指望工具能一勞永逸的解決所有問(wèn)題,有些問(wèn)題還是需要特殊處理的,但需要特殊處理的部分對(duì)絕大多數(shù)的系統(tǒng),應(yīng)該是很少的。
?
四 、使用代碼實(shí)現(xiàn)ORM框架
<?php abstract class Model{protected $pk = 'id';protected $_ID = null; protected $_tableName;protected $_arRelationMap;protected $_modifyMap;protected $is_load = false;protected $_blForDeletion;protected $_DB;public function __consturct($id = null){$this->_DB = mysql_connect('127.0.0.1','root','') ;$this->_tableName = $this->getTableName();$this->_arRelationMap = $this->getRelationMap();if(isset($id))$this->_ID = $id;}abstract protected function getTableName();abstract protected function getRelationMap();public function Load(){if(isset($this->_ID)){$sql = "SELECT ";foreach($this->_arRelationMap as $k => $v){$sql .= '`'.$k.'`,';}$sql .= substr($sql,0,strlen($sql)-1);$sql .= "FROM ".$this->_tableName." WHERE ".$this->pk." = ".$this->_ID;$result =$this->_DB->mysql_query($sql);foreach($result[0] as $k1 => $v1){$member = $this->_arRelationMap[$key];if(property_exists($this,$member)){if(is_numeric($member)){eval('$this->'.$member.' = '.$value.';');}else{eval('$this->'.$member.' = "'.$value.'";');}}}}$this->is_load = true;}public function __call($method,$param){$type = substr($method,0,3);$member = substr($method,3);switch($type){case 'get':return $this->getMember($member);break;case 'set':return $this->setMember($member,$param[0]);}return false;}public function setMember($key){if(property_exists($this,$key)){if(is_numeric($val)){eval('$this->'.$key.' = '.$val.';');}else{eval('$this->'.$key.' = "'.$val.'";');}$this->_modifyMap[$key] = 1;}else{return false;}}public function getMember($key,$val){if(!$this->is_load){$this->Load();}if(property_exists($this,$key)){eval('$res = $this->'.$key.';' );return $this->$key;}return false;}public function save(){if(isset($this->_ID)){$sql = "UPDATE ".$this->_tableName." SET ";foreach($this->arRelationMap as $k2 => $v2){if(array_key_exists( $k2, $this->_modifyMap)){eval( '$val = $this->'.$v2.';');$sql_update .= $v2." = ".$val;}}$sql .= substr($sql_update,0,strlen($sql_update));$sql .= 'WHERE '.$this->pk.' = '.$this->_ID;}else{$sql = "INSERT INTO ".$this->_tableName." (";foreach($this->arRelationMap as $k3 => $v3){if(array_key_exists( $k3,$this->_modifyMap)){eval('$val = $this->'.$v3.';');$field .= "`".$v3."`,"; $values .= $val;}}$fields = substr($field,0,strlen($field)-1);$vals = substr($values,0,strlen($values)-1);$sql .= $fields." ) VALUES (".$vals.")";}echo $sql;//$this->_DB->query($sql);}public function __destory(){if(isset($this->ID)){$sql = "DELETE FROM ".$this->_tableName." WHERE ".$this->pk." = ".$this->_ID;// $this->_DB_query($sql);}} } class User extends Model{protected function getTableName(){return "test_user";}protected function getRelationMap(){return array( 'id' => USER_ID,'user_name'=> USER_NAME,'user_age' => USER_AGE);}public function getDB(){return $this->_DB;} } $UserIns = new User(); print_r($UserIns);?>?
總結(jié)
- 上一篇: redis学习(五) redis实现购物
- 下一篇: 微信支付的坑(思路)