|
MENU
LOGIN
W3C validiation
|
boqurawa minnna ikiteiru ikiteirukara utaunnda
tenohirawo taiyo ni kazasitemireba......★
my TIPS
PEAR,XP,PHPなど覚書
:::
DB_DataObjectの使い方
Alan Knowles氏作のDB_DataObjectは使いやすいSQLビルダ。自習メモ書。
マニュアルは
demo:本クラスを使った国会議員Webサイト簡易検索: (議員の苗字を、漢字で入れてください(例:小沢):フルネームは対応してません) 違っているとか、不正確だとかの突っ込みは aki@townmedia.org まで、どんどんご指摘ください。
1 ともかく実行してみる
|
| 型 | 数値 | 実装or未実装 |
|---|---|---|
| 数値型 | 1 | 実装 |
| 文字型 | 2 | 実装 |
| 日付型 | 4 | TODO |
| 時刻型 | 8 | TODO |
| ブール | 16 | TODO |
| テクスト | 32 | TODO |
| Blob | 64 | 実装 |
| 非ヌル | 128 | 実装 |
| MYSQLの日付 | 256 | 実装 |
いずれにせよ、createTable.phpで生成されるiniファイルについては 「手動でいぢる必要わ、ない」 とマニュアルに宣言されているので、中身は気にしないことにしたい(藁
createTable.phpで作ったファイル・クラスを用いてみる。 拡張クラスを呼び出すには、 factory メソッドを使う。
require_once('DB/DataObject.php');
$options = &PEAR::getStaticProperty('DB_DataObject','options');
$options = array(
'database'=>'pgsql://hogeratta@127.0.0.1/mydb',
'schema_location' => '/tmp/DataObjects',
'class_location' => '/tmp/DataObjects',
'class_prefix' => 'DataObjects_',
'debug'=>1
);
$p = DB_DataObject::factory('postcode');
$p -> whereAdd("town_kanji LIKE '石垣市'");
$p -> whereAdd("zone_kanji LIKE '新川'");
$p -> find();
$p -> fetch();
echo $p -> new_post_code.':'.$p -> ken_kanji.':'
.$p -> town_kanji.':'.$p -> zone_kanji;
上のコードを実行すると, /tmp/DataObjects/Postcode.phpの DataObjects_Postcode クラスが呼び出され、 SELECT * FROM postcode WHERE town_kanji LIKE '石垣市' AND zone_kanji LIKE '新川' クエリが発行されて、実行結果は下記のようになる。
9070024:沖縄県:石垣市:新川
以下$p = DB_DataObject::factory('postcode');を前提として、いくつかのメソッドについてのメモ。
$p -> keys('*');
//mydb.iniでpostcode__keys(primary key)が
//指定されていないので、明示的にkeyが必要
echo $p -> count().'件';
結果は、
121208件
なお上記のように、primary keyが指定されていれば、 $p->keys('something'); は必要ない。
$object->limit(開始値,取得レコード件数); で取得範囲を指定する。DBMSによってSQL文実装が違うため [3] その相違を吸収してくれそうな予感。
$p -> whereAdd("town_kanji LIKE '石垣市'");
$p -> limit(3,6);
$p -> find();
while($p->fetch())
{
echo $p->zone_kanji."<br />";
}
結果は次のようになる [4]
伊原間
大川
大浜
川平
崎枝
白保
select文デフォルトは、* 。 項目を選択したい場合は、selectAddで明示的に指定する必要がある。 なお、その場合、一旦、 $object->selectAdd(); と初期化が必要。
$p->selectAdd();
$p->selectAdd('town_kanji');
発行されるSQL文は
SELECT town_kanji FROM postcode
複数テーブルの関連付けに関する覚え。 join とは限らない
例示のために、入江輝之氏作成の 国会議員名簿 を利用して、下記の二つのテーブルを作る。
representative.sql (衆参両院なのにrepresentativeというのは変だけど、とりあえず許してね^^;)
representativeテーブルの政党名略称カラム(たとえば自民党): party と partyテーブルの name_abbr
getLinkメソッドを使えば2つのSQL文が発行されて、目標の検索結果を得ることが出来る。
$newobj = $object->getLink(
'オブジェクトのテーブルのうち関係付けたいカラム',
'関係付け対象のテーブル名',
'同テーブルのキーになるカラム名'
);
これで$newobjが得られる
$Rep = DB_DataObject::factory('representative');
$Rep -> whereAdd("name LIKE '%石原%'");
$Rep -> find();
while($Rep->fetch()){
$party = $Rep->getLink('party','party','name_abbr');
echo $party->url;
}
上記で、「石原」という名前の議員の政党のWebページのURLが得られる。 実際は、下記の2つのSQL文が発行されている
SELECT * FROM representative WHERE name LIKE '%石原%'
SELECT * FROM party WHERE party.name_abbr = '自民党'
databasename.links.ini を作ることによって、上の過程を自動化できる。
giinという名称のデータベースならば、 giin.links.ini ファイルを schema_location のディレクトリに格納しておく。 あとは、getLink s メソッドを発行すると、前述のgetLinkメソッドと同等の結果が得られる。 ただし、getLinkと違い、オブジェクトを直接返すわけではなく、 $object->_対象テーブル名 にオブジェクトが格納される(この場合なら_party)。
[representative]
party = party:name_abbr
$Rep = DB_DataObject::factory('representative');
$Rep -> whereAdd("name LIKE '%石原%'");
$Rep -> find();
while($Rep->fetch()){
$Rep->getLinks();
echo $Rep->_party->url;
}
上で見たように、getLink(s)は、複数テーブルのキーを複数のSQL文を発行するにとどまる。 一方、selectAsとjoinAddを使うと、join文を作成できるようだ・・・・。ここんとこ、むづかしくて動作が、まだ、理解できていない [5] 。 が、とりあえず giin.links.ini を作っておき、下記のように書くと
$rep = DB_DataObject::factory('representative');
$party = DB_DataObject::factory('party');
$rep -> whereAdd("representative.name LIKE '%石原%'");
$rep -> joinAdd($party);
$rep -> find();
while($rep->fetch())
{
echo $rep->url;
}
次のようなSQLが発行され、じょいん、される。
SELECT * FROM representative
INNER JOIN party ON party.name_abbr=representative.party
WHERE representative.name LIKE '%石原%'
ただし、このままだと、同じカラム名は上書きされてしまうので(たとえばrepresentative.nameは、party.nameに上書きされる)、 selectAsメソッドを用いて、別名をつけることが出来る。
$rep = DB_DataObject::factory('representative');
$party = DB_DataObject::factory('party');
$rep -> whereAdd("representative.name LIKE '%石原%'");
$rep->selectAs();
//これで、representativeのカラム名を
//そのまま確保
$rep->joinAdd($party);
$rep->selectAs($party,'party_%s');
//partyテーブルのカラム名を
//party_をプレフィクスとした別名で確保
$rep -> find();
while($rep->fetch())
{
echo $rep-> party_url;//party_url別名として表示
}
発行されるSQLは
SELECT representative.house as house,
representative.name as name ,
....中略.....
party.name as party_name ,
party.name_abbr as party_name_abbr,
....以下略
[1 ]DataObject.phpの例ではsetStaticPropertyと誤記されている
[2 ]でも、中では、$GLOBALS['_DB_DATAOBJECT']['CONFIG']の値を使っているから、いまのところ(今の版では)StaticPropertyの意味がどこにあるかわからず、 $GLOBALS['_DB_DATAOBJECT']['CONFIG']=array(....);としても同じだと思われる 。
[3 ]PostgreSQLならSQL文で直接limit,offsetキーワードを書ける
[4 ]PostgresSQLの場合、SELECT * FROM postcode WHERE town_kanji LIKE '石垣市' LIMIT 6 OFFSET 3、というSQLが発行される
[5 ]なお、マニュアル的には、 Builds a Join Query, by adding another dataobject to this one. Be careful when using this, raw queries may be clearer than using joinAdd. なメソッド。