オブジェクト リレーショナル マッピング (略して ORM) は、オブジェクト指向データベースとリレーショナル データベースの間の不一致を解決するために設計されたテクノロジです。 簡単に言うと、ORM は、オブジェクトとデータベース間のマッピングを記述するメタデータを使用して、プログラム内のオブジェクトをリレーショナル データベースに自動的に保存します。基本的に、データをある形式から別の形式に変換します。
ORM はすべての SQL ステートメントの生成を提供し、プログラマーはデータベースの概念からはほど遠いものです。概念的要件 (HQL など) から SQL ステートメントへのマッピングにはコストはかからず、1% のパフォーマンスの低下もありません。実際のパフォーマンスへの影響はマッピング プロセス中、より具体的にはオブジェクトのインスタンス化中に発生します。
現在、PHP オープンソース用のより有名な ORM には次のものがあります:
1.推進
Propel は、PHP5 に適した ORM マッピング (オブジェクト リレーショナル マッピング) フレームワークであり、Apache Torque に基づいたオブジェクト永続化レイヤーのサポートを提供します。 XML 形式のスキーマ定義ファイルと対応する構成ファイルを通じて SQL とクラスを生成し、SQL の代わりにオブジェクトを使用してデータベース テーブルのレコードを読み書きできるようにします。 Propel は、データ モデルの SQL 定義ファイルと PHP クラスを作成するジェネレーターを提供します。開発者は、生成されたクラスを簡単にカスタマイズすることもできます。たとえば、PHP フレームワーク symfony の 1.2 より前のバージョンがデフォルトで使用されます。デフォルトの ORM フレームワークとして機能します。
公式ウェブサイト: http://www.propelorm.org/
2. 教義
Doctrine は PHP ORM フレームワークで、>=php5.2.3 バージョンで実行する必要があります。これは強力なデータ抽象化レイヤーです。
その主な機能の 1 つは、データベース クエリ シーリングを実装するためのオブジェクト指向メソッドの使用です。その最下層では、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 の操作効率と機能性のバランスを可能な限り取ることです。EZPDO は、私がこれまで使用した中で最も単純な ORM フレームワークであり、今後も統合したいと考えています。 CoolPHP SDK を使用すると、実行効率が非常に良く、機能も基本的にニーズを満たすことができますが、ESPDO の更新は比較的遅いです。
公式ウェブサイト: http://www.ezpdo.net/blog/?p=2
4.レッドビーン
RedBean は、MySQL、SQLite、PostgreSQL のサポートを提供する、使いやすい軽量の PHP ORM フレームワークです。 RedBean のアーキテクチャは非常に柔軟で、開発者はプラグインを通じて機能を簡単に拡張できます。
公式ウェブサイト: http://www.redbeanphp.com/
5.その他
国内のFleephp開発フレームワークは、TableDataGatewayに基づいたORM実装を実装しています。SQLステートメントのカプセル化を提供することに加えて、Zend FrameworkはTableGateway、TableRowSet、およびTableRowも実装しています。RailsのActiveRecord実装に似たソリューションもいくつかあります。
一般に、一般的な ORM フレームワークは、単純なアプリケーション システムの基本的なニーズを満たすことができ、開発の難易度を大幅に軽減し、開発効率を向上させることができます。ただし、SQL の最適化という点では、純粋な SQL 言語よりも劣っています。複雑な関係や SQL 埋め込み式の処理は理想的ではない可能性があります。おそらくこれは、PHP 自体のオブジェクトの永続性の問題が主な原因であり、その結果、ORM が非効率になり、一般に純粋な SQL よりも遅くなります。ただし、これらを解決する方法はあります。パフォーマンスに対する最も基本的な解決策は、Hibernate の構成は複雑ですが、2 次キャッシュとクエリ キャッシュを柔軟に使用することで問題を大幅に軽減できることです。データベースのクエリ圧力により、システムのパフォーマンスが大幅に向上します。
PHP 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); ?>
?