Hatena::ブログ(Diary)

知のレバレッジを最大化せよ このページをアンテナに追加 RSSフィード Twitter

2007-05-07

PHP5でSingletonを用いたDAOを作ってDBへのアクセスを合理化する


WEBアプリケーションを作っていて、「SQLをまとめたclass」(下記例ではtestEntity)を作っていたとしよう。そして、そのclassをエンティティごとに切り分けたり、機能系ごとに切り分けていたりしたとき、たとえばトップページなどでありもののいろいろなファイルに分散されたSQLをまとめたclassにはいっている複数のSQLをたたきたいというときに何個もコネクションを発行してしまうときがあるので、DB資源の無駄になってしまう。

そんなときにDBのコネクションは常に一個にキープしたい。といういきにいわゆる、Singletonによる実装ができる。下記が例。(実際はまだ未完成ですよ。select()に実際のSQLを書く。PEAR::DBだとdao::$_dao->_master->query($sql,$hash);とか)

注目したい点として

があります。

Singletonクラスのコンストラクタに、実際のマスターとスレーブのコネクションを作るとか(たとえばいくつか登録してあるスレーブから一個選択してとか)してあげるとサブクラスインスタンス化した時点からすぐに利用できて便利です。

dao.phpではSQLをまとめたclassは、スーパークラスとしてSingletonによるクラスdaoを指定し、このシングルトンクラスでDBコネクションを張る。


class testEntity extends dao {
	private $_dbaccess = null;

	public function __construct () {
		$this->_dbaccess = dao::getInstance();
	}


	public function select () {
		//必ずslaveかmasterか選ぶこと!!!!
		$rs = dao::$_dao->_slave->query($sql);
		return "hello world1";
	}
}


class test2Entity extends dao {
	private $_dbaccess = null;

	public function __construct () {
		$this->_dbaccess = dao::getInstance();
	}
	
	public function insert () {
		//必ずslaveかmasterか選ぶこと!!!!
		$rs = dao::$_dao->_master->query($sql,$hash);
		return "hello world2";

	}

}

class dao extends DB { //PEAR::DBを継承するとかで

	protected static $_dao = null;
	protected static $_master = null;
	protected static $_slave = null;
	
	private function __construct() {
		//複数のスレーブコネクションからひとつを選ぶなどして$this->_slaveにアサインするのもいいだろう。以下はPEAR::DB
		echo "Instance Created. Creating connection!";
		$this->_master = DB::connect($master_dsn);
		$this->_slave = DB::connect($slave_dsn);

	}

	public static function getInstance() {
		//自分があるかどうかstaticをみて確認する
		if (dao::$_dao == null) {
			dao::$_dao = new dao();
		} else {
			echo "Instance Already Exists!!";
		}
		return dao::$_dao;
	}

}


利用する側では、こんなかんじでバンバンSQLをまとめたclassをNewできる。


require_once('dao.php');

	$a =& new testEntity();
	echo $a->select();
	$b =& new test2Entity();
	echo $b->insert();


そうすると、下記のような出力を得る。(上の例では動かないですので、DBまわりはちゃんと実装するか省略してください)


Instance Created.Creating connection!

hello world1

Instance Already Exists!!

hello world2


この場合どんなに*EntityをNewしても1pageで実際にコネクションは1個しか作られないのがオツ。

mabotsmabots 2007/05/07 21:18 サブクラスのコードを実際DB::query()するところまで書きました。後は適当におねがいします

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/mabots/20070507/1178526193
リンク元
スマートフォン解析