テーブルデータゲートウェイパターンの危険。

エンタープライズアプリケーションアーキテクチャパターンの詳細については文献にまかせるとして、


Zend_Db_Table の話。

<?php
$data = array(.....);
$mediaTable = new My_Db_Table_Media( $config );
$mediaTable->insert($data);

※ My_Db_Table_Media は Zend_Db_Table_Abstract を継承したクラス。

という数行のプログラムに対して、発行されるSQL

array(4) {
  [0] => object(Zend_Db_Profiler_Query)#64 (5) {
    ["_query:protected"] => string(7) "connect"
    ["_queryType:protected"] => int(1)
    ["_startedMicrotime:protected"] => float(1241695541.3883)
    ["_endedMicrotime:protected"] => float(1241695541.3945)
    ["_boundParams:protected"] => array(0) {
    }
  }
  [1] => object(Zend_Db_Profiler_Query)#69 (5) {
    ["_query:protected"] => string(990) "SELECT
                a.attnum,
                n.nspname,
                c.relname,
                a.attname AS colname,
                t.typname AS type,
                a.atttypmod,
                FORMAT_TYPE(a.atttypid, a.atttypmod) AS complete_type,
                d.adsrc AS default_value,
                a.attnotnull AS notnull,
                a.attlen AS length,
                co.contype,
                ARRAY_TO_STRING(co.conkey, ',') AS conkey
            FROM pg_attribute AS a
                JOIN pg_class AS c ON a.attrelid = c.oid
                JOIN pg_namespace AS n ON c.relnamespace = n.oid
                JOIN pg_type AS t ON a.atttypid = t.oid
                LEFT OUTER JOIN pg_constraint AS co ON (co.conrelid = c.oid
                    AND a.attnum = ANY(co.conkey) AND co.contype = 'p')
                LEFT OUTER JOIN pg_attrdef AS d ON d.adrelid = c.oid AND d.adnum = a.attnum
            WHERE a.attnum > 0 AND c.relname = 'media' ORDER BY a.attnum"
    ["_queryType:protected"] => int(32)
    ["_startedMicrotime:protected"] => float(1241695541.4041)
    ["_endedMicrotime:protected"] => float(1241695541.4182)
    ["_boundParams:protected"] => array(0) {
    }
  }
  [2] => object(Zend_Db_Profiler_Query)#70 (5) {
    ["_query:protected"] => string(31) "SELECT NEXTVAL('media_key_seq')"
    ["_queryType:protected"] => int(32)
    ["_startedMicrotime:protected"] => float(1241695541.4225)
    ["_endedMicrotime:protected"] => float(1241695541.424)
    ["_boundParams:protected"] => array(0) {
    }
  }
  [3] => object(Zend_Db_Profiler_Query)#71 (5) {
    ["_query:protected"] => string(60) "INSERT INTO "media" ("mime", "data", "key") VALUES (?, ?, ?)"
    ["_queryType:protected"] => int(4)
    ["_startedMicrotime:protected"] => float(1241695541.4281)
    ["_endedMicrotime:protected"] => float(1241695541.4799)
    ["_boundParams:protected"] => array(3) {
      [1] => string(10) "(略)"
      [2] => string(25168) "(略)"
      [3] => string(1) "(略)"
    }
  }
}


※上は、Zend_Db_Profiler の出力結果。
厳密には例外処理とか begin とか commmit とか入るが今回は略。


のように、意図していないSQLがガンガン発行される。


パターンに限らず、オブジェクト指向の「隠蔽」という発想は結構怖い。



PHPならまだソースを読めるが、Javaで人が作ったクラスを考えなしに使っていると大変な事になるかもしれない。


教訓は「マニュアルちゃんと読もう」と「ログをちゃんと見よう」か....


あとは「一つのメソッドにいろんな処理を押し込まない」と。