• []
  • []
  •  
  • del.icio.us 
  •  
  • Yahoo!֥åޡϿ 

PRADO ActiveRecordを利用する

PHP 求人 募集 Symfony CakePHP Smarty Ruby on Rails

PRADO アクティブ・レコードを利用する 概要

データベースマッピングツールORマッパーで利用される実装法。
データベーステーブル、あるいはビューを一つのクラスとし、
メソッドを実行することでデータベースを制御する。
PRADOにはActive Recordは標準で実装されている。 PDO(もっというとTDbCommand)の場合、
bindParamメソッドでデータを追加していくのだが、
SQLであることには違いない。
ActiveRecordの場合はSQLを意識することなくデータベースを制御できるのが特徴と言える。

MySQLにtestというデータベースが標準で存在する。
そこに適当なテーブル(テーブル名users)を作ったとして、
その情報を取得、書き換えをしてみよう。
SQLは以下のようなもの。

CREATE TABLE users
(
    username VARCHAR( 20 ) NOT NULL ,
    email VARCHAR( 200 ) 
    , PRIMARY KEY ( username )
    , INDEX email_idx( email )
);

PRADO Active Recordを利用する 詳細

PRADO Active Recordを利用する 設定

設定ファイルにActiveRecordのモジュールを呼び出す設定を記述する。
これはコードジェネレータを利用する時に必要になる。

application.xml

<modules>
  ・・・
  <module id="db1">
    <database ConnectionString="mysql:host=localhost;dbname=test"
    username="dbuser" password="dbpass" Active="false" />
  </module>
  <module class="System.Data.ActiveRecord.TActiveRecordConfig"
    ConnectionID="db1" EnableCache="true" />
</modules>

PRADO コードジェネレータでActiveRecordクラスを作る

ActiveRecordはテーブル(またはビュー)に対して、
対象となる一つのクラスを要する。
Pradoのコードジェネレータを用いれば対象クラスを簡単に作成することが出来る。
格納するディレクトリを/protected/databaseとすると、

 $ prado-cli generate users Application.database.dbUsers

これでdbUsers.phpというファイルが出来上がる。
名前は何でも良いのだがクラス名が短いと他で利用しているものと被ることもあるので、
便宜上、適当な接頭辞(今回はdb)をつけている。

PRADO ActiveRecordを呼び出す

dbUsers.phpにdbUsersというクラスが出来上がるのだが、
これを呼び出すことでデータベースを利用することが出来る。

class Home extends TPage
{
  function onLoad($param)
  {
    Prado::using('Application.database.dbUsers');
    $userObjs = dbUsers::finder()->findAll();
    print_r( $userObjs );
  }
}

PRADO アクティブ・レコード 解説

dbUsersクラスはTActiveRecordを継承している。
上記のサンプルではfindallだけを使用しているが、
実際はもっと多数のメソッドがある。
詳しくはマニュアルを見て欲しい。
ここではメソッドを列挙しておく。

NameDescription
commitChangesCommit changes to the record, may insert, update or delete depending on the record state given in TObjectStateRegistery.
countFind the number of records.
deleteDeletes the current record from the database.
deleteAllDelete multiple records using a criteria.
deleteAllByPksAlias for deleteByPk().
deleteByPkDelete records by primary key.
equalsCompare two records using their primary key values (all column values if table does not defined primary keys).
findFind one single record that matches the criteria.
findAllSame as find() but returns an array of objects.
findAllByIndexFetches records using the sql clause ”(fields) IN (values)”, where fields is an array of column names and values is an array of values that the columns must have.
findAllByPksFind multiple records matching a list of primary or composite keys.
findAllBySqlFind records using full SQL, returns corresponding record object.
findByPkFind one record using only the primary key or composite primary keys.
findBySqlFind records using full SQL, returns corresponding record object.
saveSaves the current record to the database, insert or update is automatically determined.
__callDynamic find method using parts of method name as search criteria.

PRADO アクティブ・レコード 補足

ここまで見ると非常に便利なアクティブレコードなのだが、
Webアプリケーションはトレードオフのオンパレード。
何かを便利にしょうとすると何かが犠牲になっている。

今回犠牲になっているのはデータベース。
正確に言うとデータベースクエリ。つまりSQLだ。
上記のサンプルではfindAllメソッドでデータをすべて取得している。
一見すると以下のSQLを発行しているように思える。

 SELECT * FROM `user`

が、実際は違う。

実際発行されているSQLは

SHOW FULL TABLES LIKE ':table'
SHOW INDEX FROM `users`
SELECT CONSTRAINT_NAME AS con, COLUMN_NAME AS col, 
 REFERENCED_TABLE_SCHEMA AS fkschema, 
 REFERENCED_TABLE_NAME AS fktable, REFERENCED_COLUMN_NAME AS fkcol
 FROM `INFORMATION_SCHEMA`.`KEY_COLUMN_USAGE` 
 WHERE REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = 'users'
SHOW FULL FIELDS FROM `users`
SELECT * FROM `users` WHERE 1=1

PRADOのActive Recordを利用するたびにテーブル構造を調べるような仕組みになっている。
(ジェネレータの存在意義は微妙。)
データベースの速度はDB設計はもちろんクエリ数やクエリ内容によって大きく左右される。
クエリ数が多ければ多いほど遅くなる。
ということはPDOからqueryやprepareに直接SQLを入れるのと、
アクティブレコードを利用するのではクエリ数が5倍違うわけだ。

一言で言うならActiveRecordは初心者用と思っておいて良い。
中級者はなるべくSQLを使うように心がけ、
上級者、システム設計者になる場合は利用場所、利用方法などの棲み分けをキチンとしておかなければならない。


framework/prado/database/activerecord.txt · 最終更新: 2007/08/02 19:57 by dozo