CodeIgniter 下引入ORM Doctrine,codeigniterorm
CodeIgniter 下引入ORM Doctrine,codeigniterorm
做了两年的CI开发,一直使用activeRecord来操作数据库。简单,轻巧加方便。最近一个项目交给手下去做,也是采用从数据库设计入手的开发流程,现在已经上线运行。经历了理清需求,设计数据库,在CI中建立model, controller,需求变更,更改数据库,更改代码,增加需求,更改数据库等过程。回头来看,当需要了解全局代码和业务逻辑需求时,还是得从数据库入手,突然有一种厌烦的感脚:对象的属性都在数据库里,而相关的操作在代码中,觉得很分裂。回想多年前开发的C#与JAVA中都有一些好用的ORM的框架,对我来说,ORM最大的好处是隐藏数据库,项目前期设计时根据需求来设计对象,轻装上阵,不必早早地陷入增改删查中;直接利用工具将对象映射到数据库中;数据库的增改删查也都是面向对象的。
可能存在的两点顾虑:
- 既然要由对象自动映射到数据库,自然要遵守一套metaData规则才行。
- 性能问题,由ORM自动生成sql语句,性能可能不如以前。但对比框架的可读性/可维护性与少许的硬件性能成本,还是选择框架优先。另外,相信ORM的90%的性能影响不大,少许的实在ORM解决不了的问题也能提供原生的sql来解决,总体来说,是利大于弊。
(官方参考文档:http://doctrine-orm.readthedocs.org/en/latest/tutorials/getting-started.html)
开始吧,我们的目的是什么,没有蛀牙!好吧,这只是我们的一个目的,还在其它的目的:
- 根据建立的对象生成数据库;
- 新增对象持久化到数据库中;
- 能使用entity来方便查询数据里的信息并达到更改。
1. 在CI下安装doctrine
a. 最新的CI 3.0已支持composer。在application文件夹下建立composer.son文件如下。(不是在CI根目录下)。 注意autoload参数(不是官方例子中的/src/文件夹)
<span>{ </span>"require"<span>: { </span>"doctrine/orm": "2.4.*"<span>, </span>"symfony/yaml": "2.*"<span> }, </span>"autoload"<span>: { </span>"psr-0": {"": "models/entities"<span>} } }</span>
notes: 上面autoload参数很重要,因为doctrine的启动需要指明entity目录,原始例子中给定的是/src,这里我们放在CI的model/entities目录下,另外,同时创建model/generated 与 models/proxies目录,generated目录用来由数据库生成entity,proxies目录用来存放lazy load需要生成的代码.
b. 安装doctrine: composer install. 安装后目录结构如下:
2. 配置bootstrap与cli-config
在doctrine中,bootstrap负责创建entityManager,entityManager是整个doctrine对外提供的操作接口: 隐藏数据库接口,提供了对entity的查询,更新及持久化。
在bootstrap中,首先使用composer自带的功能对整个doctrine实现加载。(这里保留了composer功能,实现将doctrine引入到CI修改最小化)
创建基本的entityManager只需要两步:
- 使用setup创建config。
- 初始化数据库配置对象。
使用数据库连接对象创建entityManager后我们可能及不可耐就想用来从对象来逆向工程数据库了。别急,慢慢来。
php // bootstrap.php use Doctrine\ORM\Tools\Setup; use Doctrine\ORM\EntityManager; use Doctrine\Common\ClassLoader, Doctrine\DBAL\Logging\EchoSQLLogger, Doctrine\Common\Cache\ArrayCache; date_default_timezone_set("Asia/Shanghai"); require_once "vendor/autoload.php"; // database configuration parameters if(defined(APPPATH)) { require_once APPPATH.'config/database.php'; $conn = array( 'driver' => 'pdo_mysql', 'user' => $db['default']['username'], 'password' => $db['default']['password'], 'host' => $db['default']['hostname'], 'dbname' => $db['default']['database'] ); } else { $conn = array( 'driver' => 'pdo_mysql', 'user' => 'root', 'password' => '', 'host' => '127.0.0.1', 'dbname' => 'doctrine' ); } //Below can be exected in cli /* require_once APPPATH.'vendor/Doctrine/Common/lib/doctrine/common/ClassLoader.php'; $doctrineClassLoader = new ClassLoader('Doctrine', APPPATH.'libraries'); $doctrineClassLoader->register(); $entitiesClassLoader = new ClassLoader('models', rtrim(APPPATH, "/" )); $entitiesClassLoader->register(); $proxiesClassLoader = new ClassLoader('Proxies', APPPATH.'models/proxies'); $proxiesClassLoader->register(); */ // Create a simple "default" Doctrine ORM configuration for Annotations $isDevMode = true; $config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/models/entities"), $isDevMode); // or if you prefer yaml or XML //$config = Setup::createXMLMetadataConfiguration(array(__DIR__."/config/xml"), $isDevMode); //$config = Setup::createYAMLMetadataConfiguration(array(__DIR__."/config/yaml"), $isDevMode); $cache = new ArrayCache; $config->setMetadataCacheImpl($cache); $driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__.'/models/entities')); $config->setMetadataDriverImpl($driverImpl); $config->setQueryCacheImpl($cache); $config->setQueryCacheImpl($cache); // Proxy configuration $config->setProxyDir(__DIR__.'/models/proxies'); $config->setProxyNamespace('Proxies'); // Set up logger //$logger = new EchoSQLLogger; //$config->setSQLLogger($logger); $config->setAutoGenerateProxyClasses( TRUE ); // obtaining the entity manager global $entityManager; $entityManager = EntityManager::create($conn, $config); View Code
要让entityManager知道用哪里的对象来进行反向工程,下面这句就尤为重要了:
$config = SetupcreateAnnotationMetadataConfiguration(array(DIR."/models/entities"), $isDevMode);
(在这里也提一下,当从数据库生成entity时当然也要指明entity要放在哪个文件夹了,使用的是EntityGenerator对象,使用该对象的generate方法时指定存放的文件夹就可以了。)
官方文档中使用的是命令行的方法来进行反向工程的,我们这里也依样画葫芦,接下来创建必要的cli-config文件。这个文件相对来讲就没有bootstrap那么长了,总公只有下面两行即可:
requireonce "bootstrap.php"<span>; </span><span>return</span> DoctrineORMToolsConsoleConsoleRunnercreateHelperSet(<span>$entityManager</span>);
反向工程使用vendor/bin/中的doctrine命令:
vendor/bin/doctrine
其中常用的有如下:
vendor/bin/doctrine orm:schema-<span>tool:create vendor</span>/bin/doctrine orm:schema-tool:update --force
notes: 使用update命令新增字段不会影响原先的数据。
好吧,是不是急不可奈要试一试了,输入第一条create命令,咦,不好出现一个错误 “No Metadata Classes to process.” ,心跳加快,冷静,这是正常的,是因为我们还没建立我们想要的entity呢。
建立entity进行反向工程
1. 在/models/entities中建立我们第一个entity: Product.php
注意这里的每一个属性都protected属性,对应都有一对mutator(getter与setter)这是有什么用处的呢?由官方文档所说是用来方便doctrine来产生entity,而不是使用entity.field=foo的方式。具体在doctrine如何操作的有待进一步探索。对于主键Id是没有setter方法的,你懂的。
2. 现在我们只是定义了对象,但数据库构造是需要一些数据库属性的,类名与属性前面的metadata就是来干这个的。(定义的表名,对象属性对应的数据库字段名与字段属性)
<?<span>php </span><span>//</span><span> src/Product.php</span><span> /*</span><span>* * @Entity @Table(name="products") *</span><span>*/</span> <span>class</span><span> Product { </span><span>/*</span><span>* @Id @Column(type="integer") @GeneratedValue *</span><span>*/</span> <span>protected</span> <span>$id</span><span>; </span><span>/*</span><span>* @Column(type="string") *</span><span>*/</span> <span>protected</span> <span>$name</span><span>; </span><span>public</span> <span>function</span><span> getId() { </span><span>return</span> <span>$this</span>-><span>id; } </span><span>public</span> <span>function</span><span> getName() { </span><span>return</span> <span>$this</span>-><span>name; } </span><span>public</span> <span>function</span> setName(<span>$name</span><span>) { </span><span>$this</span>->name = <span>$name</span><span>; } }</span>
3. 下面我们就可以使用下面命令来进行反向工程了,是不是很兴奋!
vendor/bin/doctrine orm:schema-tool:update --force --dump-sql
4. 下面我们就来建立一段脚本来生成一个product并将其插入数据(持久化),你就会发现如何面向对象,隐藏数据库操作的了。
-
<?<span>php </span><span>require_once</span> "bootstrap.php"<span>; </span><span>$newProductName</span> = <span>$argv</span>[1<span>]; </span><span>$product</span> = <span>new</span><span> Product(); </span><span>$product</span>->setName(<span>$newProductName</span><span>); </span><span>$entityManager</span>->persist(<span>$product</span><span>); </span><span>$entityManager</span>-><span>flush</span><span>(); </span><span>echo</span> "Created Product with ID " . <span>$product</span>->getId() . "\n";
ログイン後にコピー
5. 下面我们就要使用cli来运行这段php脚本调用ORM框架来插入product了。
-
$<span> php createproduct.php ORM </span>$ php createproduct.php DBAL
ログイン後にコピー查看数据库,是不是发现了新的数据已经插入了,ok大功告成。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









CodeIgniter でカスタム ミドルウェアを実装する方法 はじめに: 最新の Web 開発では、ミドルウェアがアプリケーションで重要な役割を果たします。これらは、リクエストがコントローラーに到達する前または後に、共有処理ロジックを実行するために使用できます。 CodeIgniter は、人気のある PHP フレームワークとして、ミドルウェアの使用もサポートしています。この記事では、CodeIgniter でカスタム ミドルウェアを実装する方法を紹介し、簡単なコード例を示します。ミドルウェアの概要: ミドルウェアは一種のリクエストです

PHP でのデータベース操作は、オブジェクトをリレーショナル データベースにマップする ORM を使用して簡素化されます。 Laravel の EloquentORM を使用すると、オブジェクト指向構文を使用してデータベースと対話できます。モデル クラスを定義したり、Eloquent メソッドを使用したり、実際にブログ システムを構築したりすることで ORM を使用できます。

CodeIgniter ミドルウェア: アプリケーションの応答性とページ レンダリングの高速化 概要: Web アプリケーションの複雑さと対話性が増大し続ける中、開発者はアプリケーションのパフォーマンスと応答性を向上させるために、より効率的でスケーラブルなソリューションを使用する必要があります。 CodeIgniter (CI) は、多くの便利な機能を提供する軽量の PHP ベースのフレームワークであり、その 1 つがミドルウェアです。ミドルウェアは、リクエストがコントローラーに到達する前または後に実行される一連のタスクです。この記事では使い方を紹介します

Hibernate ポリモーフィック マッピングは、継承されたクラスをデータベースにマップでき、次のマッピング タイプを提供します。 join-subclass: 親クラスのすべての列を含む、サブクラス用の別個のテーブルを作成します。 table-per-class: サブクラス固有の列のみを含む、サブクラス用の別個のテーブルを作成します。 Union-subclass: join-subclass と似ていますが、親クラス テーブルがすべてのサブクラス列を結合します。

CodeIgniter フレームワークでデータベース クエリ ビルダー (QueryBuilder) を使用する方法の紹介: CodeIgniter は、開発者が Web アプリケーション開発を容易にするための強力なツールとライブラリを多数提供する軽量の PHP フレームワークです。最も印象的な機能の 1 つは、データベース クエリ ビルダー (QueryBuilder) です。これは、データベース クエリ ステートメントを構築および実行するための簡潔かつ強力な方法を提供します。この記事ではCoの使い方を紹介します。

Hibernate は、Java オブジェクトとリレーショナル データベース間のマッピングのための JavaORM フレームワークです。その ORM メカニズムには次の手順が含まれます。 注釈/構成: オブジェクト クラスは、マップされたデータベース テーブルと列を指定する注釈または XML ファイルでマークされます。セッションファクトリー: Hibernate とデータベース間の接続を管理します。セッション: データベースへのアクティブな接続を表し、クエリおよび更新操作を実行するために使用されます。永続性: save() または update() メソッドを通じてデータをデータベースに保存します。クエリ: 基準と HQL を使用して、データを取得するための複雑なクエリを定義します。

HibernateORM フレームワークには次の欠点があります。 1. クエリ結果とエンティティ オブジェクトをキャッシュするため、メモリ消費量が大きくなります。 2. アーキテクチャと構成についての深い理解が必要になるため、読み込みが遅くなり、予期しない遅延が発生します。 5. 多数のエンティティが同時にロードまたは更新されると、パフォーマンスのボトルネックが発生します。その結果、データベース間で差異が生じます。

回答: ORM (オブジェクト リレーショナル マッピング) と DAL (データベース抽象化レイヤー) は、基礎となるデータベース実装の詳細を抽象化することでコードの可読性を向上させます。詳細な説明: ORM はオブジェクト指向のアプローチを使用してデータベースと対話し、コードをアプリケーション ロジックに近づけます。 DAL は、データベース ベンダーに依存しない共通のインターフェイスを提供し、さまざまなデータベースとの対話を簡素化します。 ORM と DAL を使用すると、SQL ステートメントの使用が減り、コードがより簡潔になります。実際のケースでは、ORM と DAL により製品情報のクエリが簡素化され、コードの可読性が向上します。
