オブジェクト リレーショナル マッピング (ORM) は、オブジェクト指向データベースとリレーショナル データベース間の不一致を解決するために設計されたテクノロジーです。 簡単に言うと、ORM は、オブジェクトとデータベース間のマッピングを記述するメタデータを使用して、プログラム内のオブジェクトをリレーショナル データベースに自動的に保存します。基本的に、データをある形式から別の形式に変換します。
ORM はすべての SQL ステートメントの生成を提供し、プログラマーはデータベースの概念から離れます。概念的要件 (HQL など) から SQL ステートメントへのマッピングにはコストはかからず、1% のパフォーマンスの低下もありません。実際のパフォーマンスへの影響はマッピング プロセス中、より具体的にはオブジェクトのインスタンス化中に発生します。
現在、より有名な PHP オープンソース ORM には次のものがあります:
1. Propel
Propel は、Apache Torque に基づいたオブジェクト永続化レイヤーのサポートを提供する、PHP5 に適した ORM マッピング (オブジェクト リレーショナル マッピング) フレームワークです。 XML 形式のスキーマ定義ファイルと対応する構成ファイルを通じて SQL とクラスを生成し、SQL の代わりにオブジェクトを使用してデータベース テーブルのレコードを読み書きできるようにします。 Propel は、データ モデルの SQL 定義ファイルと PHP クラスを作成するジェネレーターを提供します。開発者は、生成されたクラスを簡単にカスタマイズすることもできます。たとえば、PHP フレームワーク symfony の 1.2 より前のバージョンは、デフォルトで使用されます。デフォルトの ORM フレームワークとして機能します。
公式 Web サイト: http://www.propelorm.org/
2. Doctrine
Doctrine は PHP ORM フレームワークであり、バージョン 5.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 を使用すると、実行効率は非常に良く、機能は基本的にニーズを満たすことができますが、EZPDO の更新は比較的遅いです。
公式 Web サイト: http://www.ezpdo.net/
4. RedBean
RedBean は、MySQL、SQLite、PostgreSQL のサポートを提供する、使いやすい軽量の PHP ORM フレームワークです。 RedBean のアーキテクチャは非常に柔軟で、開発者はプラグインを通じて機能を簡単に拡張できます。
公式ウェブサイト: http://www.redbeanphp.com/
5. その他
国内のfleephp開発フレームワークは、TableDataGatewayに基づいたORM実装を実装しており、SQLステートメントのカプセル化を提供することに加えて、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); ?>