需求
1. 为数据库连接类读数据增加缓存处理,缓存方式可以为文件、Memory Cache
先只对Memory Cache实现
2. 对现有代码不进行大的改动,方便移植
3. 数据库连接类可扩充其他功能。
客户端调用
以前的方法
$result = $db_bbs->query_memcache($sql_str);
if(!$result) {
$result = $db_bbs->get_results($sql_str);
}
现在的只要一行$db_bbs->get_results($sql_str)。
如果写个文件缓存类的实现,生成文件缓存也像操作数据库一样都用$db_bbs->get_results($sql_str);
就是说操作memory cache、文件和真正的数据库没区别,对于调用的程序是透明的。
使用装饰模式可以将对memory cache、和文件的操作独立出来。
//----------------------------------------我是分割线-------------------------------------------------
旧的数据库连接类和支持缓存的连接类都实现以下接口
//存储查询写入接口
interface interface_DB {
public function get_results($sql, $oMethod = 'A');
public function query($sql);
public function get_row($sql , $oMethod = 'A');
public function get_var($sql);
}
支持不同缓存的连接类可以对get_results等方法进行各自的实现。
//----------------------------------------我是分割线-------------------------------------------------
数据库连接类使用工厂模式构造
下面是具体代码
<?php
require_once(DBSTORE."DB_Base.php");
class StoreFactory{
static function create($db,$classname="") {
if(!$classname){
return $db;
}
if (!class_exists($classname)) {
if(include_once(DBSTORE.$classname.'.php')){
return new $classname($db);
}else{
throw new Exception ($classname .'file not found');
}
}
}
}
?>
//----------------------------------------我是分割线-------------------------------------------------
支持缓存的数据库连接类
构造函数
public function __construct(DB_Base $db){ #初始化
$this->MEM_PRE_KEY = $_SERVER['SERVER_NAME'];
$this->db = $db;
$this->mem = new Memcache;
foreach ($this->IP as $key=>$value)
{
$this->mem->addServer($value,11211,false);
}
}
get_results 实现方法
public function get_results($sql,$oMethod="A"){
if (preg_match('/(^select)/sim', $sql)) {
$this->content = $this->get_content($sql);
if ($this->content){
$this->content =unserialize($this->content);
}
if(!$this->content) {
$this->content = $this->db->get_results($sql,$oMethod);
if ($this->content){
$this->set_content($sql,serialize($this->content),$this->limit_time);
}
}}else{
$this->get_results_nocache($sql,$oMethod);
}
return $this->content;
}
没有缓存或者缓存过期时调用的方法
protected function get_results_nocache($sql,$oMethod){
$this->content = $this->db->get_results($sql,$oMethod);
return $this->content;
}
//----------------------------------------我是分割线-------------------------------------------------
<?php
define('DBSTORE',"D:/projects/dp/decorator/store/");
require_once(DBSTORE."class_storefactory.php");
$db = StoreFactory::create($DB_localhost,"MemoryStore");
$db->limit_time=10;
$r_old = $DB_localhost->get_results("select phraseid,varname,text from phrase phraseid limit 0,1#yiduo ");
$r = $db->get_results("select phraseid,varname,text from phrase phraseid limit 0,1#yiduo ");
if($r_old==$r) {
print_r("OK");
}
?>
//----------------------------------------我是分割线-------------------------------------------------
利用装饰模式可以为数据库连接类扩展功能
如果你写个数据库日志类DB_LOG
可以这样建一个对象
$db = StoreFactory::create($DB_MemoryStore,"DB_LOG");
那$db 类就有了数据库日志记录功能,同时还有memory cache的功能
数据库日志记录功能本身不和DB_MemoryStore类耦合,DB_MemoryStore类的代码不会特别庞大